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代码发送的文件的大小要大得多(即如果你没有压缩它)。尝试使用任何图像编辑器打开此文件,它将作为损坏的文件打开(您将无法看到图像)。

现在用记事本打开文件。可以看到,除了乱码的二进制数据外,还有一些可用的文本。例子: - 内容处置:表单数据;……等等等等。此文本是您的“参数无效”异常的罪魁祸首。在 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 回答