2

我有一个应用程序要求用户通过 Flash 上传照片。Flash 然后把这张照片变成一个字节数组。这是该代码:

 var rect:Rectangle=new Rectangle(0,0,imageWidth,imageHeight);

// create BitmapData
var bmd:BitmapData=new BitmapData(imageWidth,imageHeight,true,0);
bmd.draw(myMovieClip);// get the image out of the MovieClip

// create byte array
var binaryData:ByteArray = new ByteArray();
binaryData.position=0;// start at the beginning
binaryData.writeBytes(bmd.getPixels(rect));

创建字节数组后,将对其进行 base64 编码并发布到包含 .ashx 处理程序的 IIS 服务器。在处理程序 ProcessRequest 方法中,以下代码用于将数据写入文件:

  try
  {
      // Convert from base64string to binary array and save
      byte[] contents = Convert.FromBase64String(encodedData); //encodedData is the Base64 encoded byte array from flash
      File.WriteAllBytes(fullPath, (byte[])contents);
      context.Response.Write("result=1");
  }
  catch (Exception ex) 
  { 
     context.Response.Write("errMsg=" + ex.Message + "&result=0"); 
  }

到目前为止,一切都很好。到目前为止没有问题。

检索存储在文件中的字节数据并尝试在 C# 中的服务器端重新创建图像后,会出现此问题。

当我尝试以下操作时:

try
{
    var fileBytes = File.ReadAllBytes(path);
    Bitmap bmp;
    using (var ms = new MemoryStream(fileBytes))
    {
        ms.Position = 0;
        using (var i = Image.FromStream(ms, false, true))
        {
        bmp = new Bitmap(i);
        }
    }
}
catch (Exception ex)
{
    //error: ex.Message is always “the parameter is not valid”
}

程序总是在这一行抛出消息“参数无效”</p>

using (var i = Image.FromStream(ms, false, true))

任何意见是极大的赞赏。

4

2 回答 2

3

BitmapData.getPixels()只是每个像素的 32 位 uint 值 (ARGB) 的 ByteArray,您确定 C#Image.FromStream可以正确处理这种格式吗?作为替代方案,您可以将图像编码为 PNG 或 JPG 字节(有几个 PNG/JPG 编码器、flex版本或as3corelib

于 2013-01-25T19:26:49.103 回答
0

事实证明 fsbmain 上面是正确的。Image.FromStream没有能力从中获取数据BitmapData.getPixels()并从中创建图像。

为了回到原始图像,我需要使用Bitmap.SetPixel()并循环设置 ARGB 值的字节数组,如下所示:

(请注意,高度和宽度被添加到字节数组中。这就是为什么我使用Buffer.BlockCopy将数组拆分为我需要的部分)

static void Main(string[] args)
            {
                string path = @"C:\data\TUIxMTA0ODM5\imagea.b64";
                string imagepath = @"C:\data\newPic.jpg";

                try
                {
                    //get the data from the file
                    var f = File.ReadAllBytes(path);

                    //get the height and width of the image
                    var newArr = new byte[4];
                    Buffer.BlockCopy(f, 0, newArr, 0, 4);
                    var height = ReadShort(newArr, 0);
                    var width = ReadShort(newArr, 2);

                    //get the pixel data
                    var myArr = new byte[f.Length - 4];
                    Buffer.BlockCopy(f, 4, myArr, 0, f.Length - 4);

                    //create the new image
                    var bmp = new Bitmap(width, height);
                    int counter = 0;
                    for (int x = 0; x < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            bmp.SetPixel(x, y, Color.FromArgb(myArr[counter], myArr[++counter], myArr[++counter], myArr[++counter]));
                            counter++;
                        }
                    }
                    bmp.Save(imagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }

            public static short ReadShort(byte[] buffer, int offset)
            {
                return (short)((buffer[offset + 0] << 8) + buffer[offset + 1]);
            }

我希望这有帮助。

于 2013-01-26T21:43:21.160 回答