【发布时间】:2012-04-05 08:10:35
【问题描述】:
如何使用 PDFSharp 从 PDF 文档中提取经过 FlateDecoded(如 PNG)解码的图像?
我在 PDFSharp 示例中发现了该评论:
// TODO: You can put the code here that converts vom PDF internal image format to a
// Windows bitmap
// and use GDI+ to save it in PNG format.
// [...]
// Take a look at the file
// PdfSharp.Pdf.Advanced/PdfImage.cs to see how we create the PDF image formats.
有人有解决这个问题的办法吗?
感谢您的回复。
编辑:因为我无法在 8 小时内回答我自己的问题,所以我这样做了:
感谢您的快速回复。
我在方法“ExportAsPngImage”中添加了一些代码,但没有得到想要的结果。它只是提取了更多的图像 (png),它们没有正确的颜色并且被扭曲了。
这是我的实际代码:
PdfSharp.Pdf.Filters.FlateDecode flate = new PdfSharp.Pdf.Filters.FlateDecode();
byte[] decodedBytes = flate.Decode(bytes);
System.Drawing.Imaging.PixelFormat pixelFormat;
switch (bitsPerComponent)
{
case 1:
pixelFormat = PixelFormat.Format1bppIndexed;
break;
case 8:
pixelFormat = PixelFormat.Format8bppIndexed;
break;
case 24:
pixelFormat = PixelFormat.Format24bppRgb;
break;
default:
throw new Exception("Unknown pixel format " + bitsPerComponent);
}
Bitmap bmp = new Bitmap(width, height, pixelFormat);
var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, pixelFormat);
int length = (int)Math.Ceiling(width * bitsPerComponent / 8.0);
for (int i = 0; i < height; i++)
{
int offset = i * length;
int scanOffset = i * bmpData.Stride;
Marshal.Copy(decodedBytes, offset, new IntPtr(bmpData.Scan0.ToInt32() + scanOffset), length);
}
bmp.UnlockBits(bmpData);
using (FileStream fs = new FileStream(@"C:\Export\PdfSharp\" + String.Format("Image{0}.png", count), FileMode.Create, FileAccess.Write))
{
bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
}
这是正确的方法吗?还是我应该选择其他方式?非常感谢!
【问题讨论】:
-
关于24 bpp:一种格式是RGB,另一种是BGR。所以 Marshal.Copy 不行,你必须在复制时交换字节。所以颜色不对。您不会在 DWORD 边界处对齐 BMP 数据。这应该可以解释失真。
-
fyi,
bmpData.Scan0.ToInt32()在 64 位系统上会失败,需要更改为 ToInt64