.Net提取PDF中1bpc黑白图像转JPG/TIFF时Bitmap创建异常求助
解决1bpc黑白PDF图像提取后转Bitmap的异常问题
问题核心在于:你直接用iText7返回的原始像素流创建Bitmap——1bpc图像的GetImageBytes()返回的是无格式的原始像素字节,没有Bitmap能识别的文件头(比如BMP/TIFF的格式标识、尺寸信息等),所以Bitmap构造函数无法解析,抛出"Parameter is not valid"异常。
下面是直接操作原始像素生成Bitmap的具体方案:
修改后的代码实现
PdfImageXObject imageObject = imageData.GetImage(); if (imageObject == null) { Console.WriteLine("Image could not be read."); } else { // 获取图像核心元数据 int width = imageObject.GetWidth(); int height = imageObject.GetHeight(); int bitsPerComponent = imageObject.GetBitsPerComponent(); // 非1bpc图像沿用原有逻辑 if (bitsPerComponent != 1) { using (var ms = new MemoryStream(imageObject.GetImageBytes())) { using (Bitmap temp = new Bitmap(ms)) { temp.Save("output.jpg", ImageFormat.Jpeg); temp.Save("output.tiff", ImageFormat.Tiff); } } return; } // 处理1bpc原始像素数据 byte[] rawPixels = imageObject.GetImageBytes(); // 创建1位黑白格式的Bitmap using (Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format1bppIndexed)) { BitmapData bmpData = bitmap.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed); int bytesPerRow = (width + 7) / 8; // 每行所需字节数(向上取整) // 反转行顺序:PDF图像行从上到下,Bitmap缓冲区行从下到上 for (int y = 0; y < height; y++) { int sourceRowIdx = y * bytesPerRow; int destRowIdx = (height - 1 - y) * bmpData.Stride; // 处理每字节的位反转:PDF通常0=白、1=黑,Bitmap的1bpp格式正好相反 for (int xByte = 0; xByte < bytesPerRow; xByte++) { byte sourceByte = rawPixels[sourceRowIdx + xByte]; byte destByte = (byte)~sourceByte; // 反转每一位 Marshal.WriteByte(bmpData.Scan0, destRowIdx + xByte, destByte); } } bitmap.UnlockBits(bmpData); // 保存为目标格式 bitmap.Save("output.jpg", ImageFormat.Jpeg); bitmap.Save("output.tiff", ImageFormat.Tiff); } }
关键细节说明
- 像素格式选择:必须使用
Format1bppIndexed,这是.NET唯一支持的1位黑白像素格式 - 行顺序调整:PDF图像的像素行是从上到下存储,而Bitmap的内存缓冲区是从下到上排列,所以需要反转行索引才能得到正确的图像方向
- 位值反转:PDF的1bpc标准中通常用0表示白色、1表示黑色,但Bitmap的1bpp格式正好相反,所以需要用
~操作符反转每个字节的位;如果你的PDF图像是白底黑字显示,可根据实际效果去掉反转逻辑 - 字节对齐:每行的字节数需要向上取整为
(width +7)/8,Bitmap的Stride属性会自动处理内存对齐,直接按行复制即可
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

