0

我有以下代码,它采用我生成的字节数组并将它们写入该位图。如果我将像素格式设置为 Format4bppIndexed,那么我会得到一个重复宽度 4 次的可读图像,如果我将其设置为 Format1bppIndexed(这是正确的设置),那么我会得到一个不可读的大图像。

该图像是解码的 Jbig2 图像,我知道字节是正确的,我似乎无法弄清楚如何将其转换为 1bpp 可读格式。

有没有人对此事有任何建议

        Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format1bppIndexed);

        //Create a BitmapData and Lock all pixels to be written           
        BitmapData bmpData = bitmap.LockBits(
                             new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                             ImageLockMode.WriteOnly, bitmap.PixelFormat);

        //Copy the data from the byte array into BitmapData.Scan0
        Marshal.Copy(newarray, 0, bmpData.Scan0, newarray.Length);
        //Unlock the pixels
        bitmap.UnlockBits(bmpData);
4

2 回答 2

0

以下可能有效,但如果我没记错的话,Stride有时会产生效果并且简单的块复制是不够的(必须逐行使用)。

Bitmap bitmap = new Bitmap(
    width, 
    height, 
    System.Drawing.PixelFormat.Format16bppGrayScale
    );

要处理您想要的步幅:

    BitmapData^ data = bitmap->LockBits(oSize, 
        ImageLockMode::ReadOnly, bitmap->PixelFormat);
    try {
        unsigned char *pData = (unsigned char *)data->Scan0.ToPointer();

        for( int x = 0; x < bmpImage->Width; ++x )
        {
            for( int y = 0; y < bmpImage->Height; ++y )
            {
                // Note: Stride is data width of scan line rounded up
                //       to 4 byte boundary.  
                // Requires use of Stride, not (width * pixelWidth)
                int ps = y*bmpImage->Width*(nBitsPerPixel / 8)
                         + x * (nBitsPerPixel / 8);
                int p = y * data->Stride + x * (nBitsPerPixel / 8);
                Byte lo = newarray[ps + 1];
                Byte hi = newarray[ps + 0];
                pData[p + 1] = lo;
                pData[p + 0] = hi;
            }
        }
    } finally {
        bmpImage->UnlockBits(data);
    }

注意:这是用 C++/CLI 编写的。如果您需要 C# 等效项来执行此处的任何操作,请告诉我。(另外,我从位图读取而不是写入位图中提取它,所以它可能有点粗糙,但希望能给你这个想法......)

于 2013-11-13T16:55:25.980 回答
0

我想通了虽然我仍然不确定它为什么重要。

基于此 stackoverflow 发布How can I load the raw data of a 48bpp image into a Bitmap?

我使用 WPF 类而不是 GDI 并编写了这样的代码

var bitmap = new WriteableBitmap(width, height, 96, 96,           System.Windows.Media.PixelFormats.BlackWhite, null);
bitmap.WritePixels(new System.Windows.Int32Rect(0, 0, width, height), newarray, stride, 0);     
MemoryStream stream3 = new MemoryStream();
var encoder = new TiffBitmapEncoder ();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
encoder.Save(stream3);

这正确地创建了图像。

如果有人对为什么会出现这种情况有任何见解,请在下面发表评论

现在主要工作的端口(大量清理代码)基于 JPedal Big2 解码器到 .NET 的 java 实现。如果有人知道任何有兴趣的人将他们发送到这里 https://github.com/devteamexpress/JBig2Decoder.NET

于 2013-11-14T09:42:07.473 回答