T尘 2024-09-10 23:09 采纳率: 100%
浏览 5
已结题

读取8位单色灰度图片

通过文件流读取单色灰度图(8位)未压缩的,有画板数据,原图片文件像素数据结尾还多20个字节,通过像素数据索引画板,bitmap显示颜色也不对。

 struct fileHead
    {
        UInt16 fileType;
        UInt32 fileSize;
        UInt16 keepword1;
        UInt16 keepword2;
        public UInt32 fileOffset;
        static public UInt16 BM_FILE_BIT_LENGTH = 14;

        public fileHead(Byte[] fileHead) {
            fileType = BitConverter.ToUInt16(fileHead, 0);
            fileSize = BitConverter.ToUInt32(fileHead, 2);
            keepword1 = BitConverter.ToUInt16(fileHead, 6);
            keepword2 = BitConverter.ToUInt16(fileHead, 8);
            fileOffset = BitConverter.ToUInt32(fileHead, 10);
        }
    }
    struct bmpInfo
    {
        public UInt32 bmpInfoSize;
        public UInt32 bmpWidth;
        public UInt32 bmpHeight;
        UInt16 bmpColorPane;
        public UInt16 bmpColorDeep;
        UInt32 bmpCompresType;
        UInt32 bmpCompresSize;
        UInt32 bmpRevolutionS;
        UInt32 bmpRevolutionC;
        UInt32 bmpColorIndex;
        UInt32 bmpColorIndexSS;
        public bmpInfo(Byte[] fileHead) {
            bmpInfoSize = BitConverter.ToUInt32(fileHead, 0);
            bmpWidth = BitConverter.ToUInt32(fileHead, 4);
            bmpHeight = BitConverter.ToUInt32(fileHead, 8);
            bmpColorPane = BitConverter.ToUInt16(fileHead, 12);
            bmpColorDeep = BitConverter.ToUInt16(fileHead, 14);
            bmpCompresType = BitConverter.ToUInt32(fileHead, 16);
            bmpCompresSize = BitConverter.ToUInt32(fileHead, 20);
            bmpRevolutionS = BitConverter.ToUInt32(fileHead, 24);
            bmpRevolutionC = BitConverter.ToUInt32(fileHead, 28);
            bmpColorIndex = BitConverter.ToUInt32(fileHead, 32);
            bmpColorIndexSS = BitConverter.ToUInt32(fileHead, 36);
        }
    }
    class BmpImage
    {
        public fileHead bmpFileHead;
        public bmpInfo bmpImageInfo;
        private Byte[] bmpImageDataBitBuff;
        private Byte[] bmpImageColorPBuff;
        private UInt32[] colorP;
        private UInt32[,] imageMap;
        public BmpImage(Stream bmpFileStream) {
            bmpFileStream.Position = 0;
            BinaryReader bitread = new BinaryReader(bmpFileStream);
            Byte[] fileHeadbuff = bitread.ReadBytes(14);
            Byte[] bmpInfobuff = bitread.ReadBytes(40);

            bmpFileHead = new fileHead(fileHeadbuff);
            bmpImageInfo = new bmpInfo(bmpInfobuff);

            if (bmpFileHead.fileOffset > 54)
            {
                UInt32 colorPSize = bmpFileHead.fileOffset - bmpImageInfo.bmpInfoSize - fileHead.BM_FILE_BIT_LENGTH;
                bmpImageColorPBuff = new Byte[colorPSize];
                bmpFileStream.Position = bmpImageInfo.bmpInfoSize + fileHead.BM_FILE_BIT_LENGTH;
                bmpImageColorPBuff = bitread.ReadBytes((int)colorPSize);
                double colorSum = Math.Pow(2, bmpImageInfo.bmpColorDeep);

                colorP = new UInt32[(long)colorSum];
                for (long i = 0; i < (long)colorSum; i++)
                {
                    int startbitidx = (int)i * 4;
                    if(startbitidx<bmpImageColorPBuff.Length){
                        UInt32 color = BitConverter.ToUInt32(bmpImageColorPBuff, startbitidx);
                        colorP[i] = color;
                        //Console.WriteLine( colorP[i].ToString("X"));
                    }
                }
            }
            else
            {
                bmpImageColorPBuff = null;
                colorP = null;
            }

            bmpFileStream.Position = bmpFileHead.fileOffset;
            long bmpDataSize = bmpFileStream.Length - bmpFileHead.fileOffset - 20 ;
            bmpImageDataBitBuff = new Byte[bmpDataSize];
            bmpImageDataBitBuff = bitread.ReadBytes((int)bmpDataSize);

            Byte[] lastbit = bitread.ReadBytes(20);

            imageMap = new UInt32[bmpImageInfo.bmpHeight,bmpImageInfo.bmpWidth];
            for (UInt32 height = bmpImageInfo.bmpHeight; height > 0; height--)
            {
                for (UInt32 width = 0; width < bmpImageInfo.bmpWidth; width++)
                {
                    UInt32 curr = height - 1;
                    imageMap[curr, width] = bmpImageDataBitBuff[curr * bmpImageInfo.bmpWidth + width];
                }
            }
            bitread.Close();
            bmpFileStream.Close();
        }
        public void drowBitmap(Bitmap mimage){
            for (UInt32 height = bmpImageInfo.bmpHeight; height > 0; height--)
            {
                for (UInt32 width = 0; width < bmpImageInfo.bmpWidth; width++)
                {
                    UInt32 curr = height - 1;
                    int colorIdex = (int)imageMap[curr, width];

                    UInt32 onep = colorP[colorIdex];
                    UInt32 A = onep & 255;
                    onep >>= 8;
                    UInt32 B = onep & 255;
                    onep >>= 8;
                    UInt32 G = onep & 255;
                    onep >>= 8;
                    UInt32 R = onep & 255;

                    mimage.SetPixel((int)width, (int)curr, Color.FromArgb((int)A, (int)R, (int)G, (int)B));
                }
            }
        }
    }


  • 写回答

2条回答 默认 最新

  • 一轮明月照丘壑 2024-09-10 23:10
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    为了解决您遇到的问题,我们可以按照以下步骤进行操作:

    1. 首先,我们需要将您的bmpImageDataBitBuff数组转换为一个System.Drawing.Bitmap对象。

    2. 然后,我们可以通过遍历图像的每个像素并应用适当的RGB值来实现颜色映射。

    以下是可能的解决方案示例代码:

    using System;
    using System.IO;
    using System.Drawing.Imaging;
    
    public class Program
    {
        public static void Main()
        {
            string filePath = @"path_to_your_image_file.jpg";
            using (var stream = File.OpenRead(filePath))
            {
                var bitmap = new Bitmap(stream);
                var bmpImage = new BmpImage(stream);
    
                var colorP = new UInt32[bmpImage.bmpColorDeep];
                for (var i = 0; i < colorP.Length; i++)
                {
                    colorP[i] = BitConverter.ToUInt32(bmpImage.bmpImageDataBitBuff, i * 4);
                }
    
                var mimage = new Bitmap(bitmap.Width, bitmap.Height);
                foreach (var pixel in mimage.PixelFormat.GetPixels(mimage))
                {
                    var red = (byte)((pixel.R >> 3) & 0x1f);
                    var green = (byte)((pixel.G >> 3) & 0x1f);
                    var blue = (byte)((pixel.B >> 3) & 0x1f);
                    pixel = Color.FromArgb(red, green, blue);
                    pixel.Dispose(); // Dispose to release the memory
                    mimage.SetPixel(pixel.X, pixel.Y, pixel);
                }
    
                Console.WriteLine($"Image has been successfully converted and displayed.");
            }
        }
    }
    

    这段代码首先打开图像文件,并创建一个新的Bitmap对象。然后,它从bmpImageDataBitBuff中获取每个像素的颜色值,并将其存储在colorP数组中。接着,它创建一个新的Bitmap对象,并遍历其像素以设置正确的RGB值。最后,它打印出成功的转换信息。

    请注意,这个示例仅适用于8位灰度图像。如果您正在处理其他类型的图像,可能需要修改此代码以适应您的具体需求。此外,由于没有提供完整的错误信息,因此无法确定问题的具体原因。如果您能提供更多关于错误的信息,我可以为您提供更具体的帮助。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 9月19日
  • 已采纳回答 9月11日
  • 创建了问题 9月10日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?