2

ギャラリーから画像を選択してストリームをアップロードできますが、「パラメーターが無効です」というエラーが表示されます。WCFで画像に変換しようとしたとき。

Android コードは REST サービスへの接続を作成し、イメージを Byte[] としてアップロードします。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  if (resultCode == RESULT_OK){
    Uri targetUri = data.getData();

    Bitmap bitmap;
    try {
      bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
      ByteArrayOutputStream out = new ByteArrayOutputStream();

      bitmap.compress(Bitmap.CompressFormat.JPEG, 6, out);

      DefaultHttpClient httpClient = new DefaultHttpClient();

      byte[] sendData = out.toByteArray();

      HttpPost postRequest = new HttpPost("http://www.thehost.dk/MobileService/Service.svc/uploadpicture/");
      ByteArrayBody bab = new ByteArrayBody(sendData, "picture.jpg");
      MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
      reqEntity.addPart("image", bab);
      postRequest.setEntity(reqEntity);
      httpClient.execute(postRequest);

WCF C# コードはストリームを受信し、イメージに変換しようとしますが、エラーを受け取ります:

    public void UploadPicture(Stream imageData)
    {
        try
        {
            byte[] image = StreamToBytes(imageData);

            ImageConverter imageConverter = new ImageConverter();
            Image img = imageConverter.ConvertFrom(image) as Image; <-- Exception happens here

            SaveImage(img);
        }
        catch (Exception ex)
        {
            Log(ex.ToString());
        }
    }

    private byte[] StreamToBytes(Stream stream)
    {
        byte[] output = new byte[0];
        byte[] stream_array = new byte[0];
        byte[] buffer = new byte[1024];
        int read;

        while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            stream_array = new byte[output.Length + read];
            output.CopyTo(stream_array, 0);
            Array.Copy(buffer, 0, stream_array, output.Length, read);
            output = stream_array;
        }

        return output;
    }

私は何を間違っていますか?

4

1 に答える 1

5

最初に問題が発生した理由を説明してから、解決策を示します。コードでこの実験を試してください。使用した次のコードの代わりに、その下のコードに置き換えてください。

       public void UploadPicture(Stream imageData)
       {
           try
           {
               byte[] image = StreamToBytes(imageData);
               ImageConverter imageConverter = new ImageConverter();
               Image img = imageConverter.ConvertFrom(image) as Image;
               SaveImage(img);
           }
           catch (Exception ex)
           {
               Log(ex.ToString());
           }
       }

と置換する、

    public void UploadPicture (Stream imageData)
    {
        try
        {
            byte[] buffer = new byte[10000];
            imagedata.Read(buffer, 0, 10000);
            FileStream f = new FileStream("D:\\FileUpload\\SubjectFront.JPG", FileMode.OpenOrCreate);
            f.Write(buffer, 0, buffer.Length);
            f.Close();
            imagedata.Close();
        }
        catch (Exception ex)
        {
        } 
    }

このコードは例外なく実行され(私は信じています)、「保存された」パスに画像ファイルがあります。D:\FileUploadに作成されたファイルに注目してください。ファイルのサイズは、Androidコードによって送信されるファイルのサイズよりもはるかに大きくなります(つまり、圧縮していない場合)。このファイルを任意の画像エディタで開こうとすると、破損したファイルとして開きます(画像を表示できなくなります)。

次に、メモ帳でファイルを開きます。文字化けしたバイナリデータに加えて、利用可能なテキストもいくつかあることがわかります。例: - Content-Disposition:form-data;…..何とか何とか。このテキストは、「パラメータが無効です」という例外の原因です。JavaでMultipartを使用している間、このテキストを追加し、バイトストリームに変換される画像データに沿って送信します。なぜそうなるのかわかりません。次に、人間が読めるテキストをすべて削除して、ファイルを保存します。任意の画像エディタとビオラでファイルを開きます。画像があります。

ここでの解決策は、WCFメソッドによって受信されるストリームからこのテキストを削除するコードを作成することです。私は、効率的に仕事をする非常に美しいパーサーが書かれているのを見つけました(Anthonyに感謝します)。ここ( http://multipartparser.codeplex.com/ )で見つけることができます。この.csファイルをプロジェクトに追加して、次のようにします。

    public string UploadPicture (Stream imagedata)
    {
        MultipartParser parser = new MultipartParser(imagedata);

        if (parser.Success)
        {
            string fileName = parser.Filename;
            string contentType = parser.ContentType;
            byte[] fileContent = parser.FileContents;
            System.Drawing.Image image = byteArrayToImage(fileContent);
            image.Save("D:\\FileUpload\\" + fileName);
            return "Success !!!";
         }
         else
         {
            return "Exception!!!";
         }
   }

byteArrayToImageの実装は次のとおりです。

public System.Drawing.Image byteArrayToImage(byte[] byteArrayIn)
{
    MemoryStream ms = new MemoryStream(byteArrayIn);
    System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
    return returnImage;
}

お役に立てば幸いです…</p>

于 2012-10-06T08:08:15.240 に答える