【问题标题】:Bitmap Image from Hex string - extra bytes being added来自十六进制字符串的位图图像 - 添加额外的字节
【发布时间】:2014-02-27 01:29:02
【问题描述】:

我有一个来自 postscript 文件的十六进制字符串。

<< /ImageType 1
/Width 986 /Height 1
/BitsPerComponent 8
/Decode [0 1 0 1 0 1]
/ImageMatrix [986 0 0 -1 0 1]
/DataSource <
803fe0503824160d0784426150b864361d0f8844625138a4562d178c466351b8e4763d1f904864523924964d27944a6552b964b65d2f984c665339a4d66d379c4e6753b9e4f67d3fa05068543a25168d47a4526954ba648202
> /LZWDecode filter >> image } def

以下是我正在使用的方法。更新颜色的方法我已经注释掉了。

public static void ProcessImageColourMapping()
{
    string imageDataSource = "803fe0503824160d0784426150b864361d0f8844625138a4562d178c466351b8e4763d1f904864523924964d27944a6552b964b65d2f984c665339a4d66d379c4e6753b9e4f67d3fa05068543a25168d47a4526954ba648202";
    string imageDataSourceUpdated = GetUpdatedImage(imageDataSource);
}

public static string GetUpdatedImage(string strImageDataSource)
{
    string imageDataSourceUpdated = "";

    byte[] imageBytes = StringToByteArray(strImageDataSource);
    Bitmap bitmapImage = ByteArrayToBitmap(imageBytes);
    //UpdateColour(bitmapImage);
    byte[] imageBytesUpdated = BitmapToByteArray(bitmapImage);
    imageDataSourceUpdated = ByteArrayToString(imageBytesUpdated);

    return imageDataSourceUpdated;
}

public static byte[] StringToByteArray(String imageHexString)
{
    int numberOfChars = imageHexString.Length / 2;
    byte[] byteArray = new byte[numberOfChars];
    using (var sr = new StringReader(imageHexString))
    {
        for (int i = 0; i < numberOfChars; i++)
            byteArray[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
    }
    return byteArray;
}

public static Bitmap ByteArrayToBitmap(byte[] byteArray)
{
    int width = 986; //width and height are taken from postscript file for testing a single hex string.
    int height = 1; 
    Bitmap bitmapImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
    BitmapData bmpData = bitmapImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);            
    try
    {                
        Marshal.Copy(byteArray, 0, bmpData.Scan0, byteArray.Length);
    }
    finally
    {
        bitmapImage.UnlockBits(bmpData);                
    }
    return bitmapImage;
}

public static byte[] BitmapToByteArray(Bitmap bitmap)
{
    BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
    int numbytes = bmpdata.Stride * bitmap.Height;
    byte[] bytedata = new byte[numbytes];
    try
    {
        Marshal.Copy(bmpdata.Scan0, bytedata, 0, numbytes);            
    }
    finally
    {
        bitmap.UnlockBits(bmpdata);
    }
    return bytedata;
}

public static string ByteArrayToString(byte[] byteArray)
{
    StringBuilder hex = new StringBuilder(byteArray.Length * 2);
    foreach (byte b in byteArray)
    {
        hex.AppendFormat("{0:x2}", b);
    }
    return hex.ToString();
}

问题:
在下面的代码中,我没有为传入的十六进制字符串 imageDataSource 更新任何内容。
将其转换为 byte[] - 然后转换为 Bitmap - 返回 byte[] - 最后返回 Hex 字符串。

所以,imageDataSourceUpdated 应该与 imageDataSource 具有相同的值。
但是,当我最终检查imageDataSourceUpdated 的值时,结果为:

803fe0503824160d0784426150b864361d0f8844625138a4562d178c466351b8e4763d1f904864523924964d27944a6552b964b65d2f984c665339a4d66d379c4e6753b9e4f67d3fa05068543a25168d47a4526954ba64820200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.....
附加了这么多零。

可以请指导我在这里缺少什么。

【问题讨论】:

  • 您是否尝试在您的ByteArrayToBitmap 方法中使用PixelFormat.Format8bppIndexed 而不是PixelFormat.Format32bppPArgb

标签: c# colors bitmap postscript


【解决方案1】:

您正在传递一些输入字符串,但图像的宽度(因此是字节数组大小的 1/4)在您的示例中设置为 986,这将产生您观察到的行为 - 您不是实际上传递了986 * 4 字节的数据,但位图确实有那么多。因此,您将获得实际复制到位图的前 X 个字节,然后全为零。换句话说,您的问题似乎出在您的示例数据上,而不是方法本身 - 那些工作正常。

【讨论】:

  • 嗨 Luaan,我从我们客户的 postscript 文件中得到这个输入的 HEX 字符串和大小。您是否知道仅通过使用十六进制字符串来创建“正确大小”的位图的任何方法?谢谢!
  • @iniki 您必须在图像本身之前读取数据,例如40 45 1 [ 40 0 0 -45 0 45 ]。这告诉您位图的参数——前三个数字是宽度、高度和每像素字节数。那么数据字符串的长度应该是width * height * BPP * 2,并且您应该创建正确大小和格式的位图。在我的例子中,这将是例如。 new Bitmap(40, 45, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  • '在图像本身之前读取数据',你的意思是 /ImageMatrix [986 0 0 -1 0 1] 请看看我更新的问题 - 从 ps 文件中添加了整个图像 def 块跨度>
  • @iniki 在您的示例中,它是宽度、高度和 BitsPerComponent。但是,现在看到整个定义,问题就更加复杂了,因为图像数据实际上是使用 LZW 压缩的。因此,您应该期待 986 字节的数据(986 宽,1 高,每像素 1 字节)。所以 - 获取数据字符串,将其转换为字节[],解压缩(例如sharplzw.sourceforge.net),将位图创建为new Bitmap(986, 1, PixelFormat.Format8bppIndexed);,进行操作,获取字节[],压缩,编码为数据字符串你就完成了。
猜你喜欢
  • 2014-10-29
  • 1970-01-01
  • 2012-05-28
  • 2011-03-01
  • 2015-11-20
  • 2015-04-10
  • 2019-07-27
  • 1970-01-01
  • 2012-01-24
相关资源
最近更新 更多