當通過iTextSharp解碼PDF中的圖像爲FlateDecode
時,圖像失真,我似乎無法弄清楚原因。爲什麼使用iTextSharp解碼FlateDecode時圖像失真?
公認的bpp是Format1bppIndexed
。如果我將PixelFormat
修改爲Format4bppIndexed
,則圖像在某種程度上可識別(收縮,着色關閉但可讀),並以水平方式複製4次。如果我將像素格式調整爲Format8bppIndexed
,則它在某種程度上也可以識別,並以水平方式重複8次。
下面的圖片是在Format1bppIndexed
像素格式的方法之後。不幸的是,由於安全限制,我無法顯示其他人。
的代碼被認爲是下面基本上是單一的解決方案,我所遇到的周圍既SO和web散落。
int xrefIdx = ((PRIndirectReference)obj).Number;
PdfObject pdfObj = doc.GetPdfObject(xrefIdx);
PdfStream str = (PdfStream)(pdfObj);
byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)str);
string filter = ((PdfArray)tg.Get(PdfName.FILTER))[0].ToString();
string width = tg.Get(PdfName.WIDTH).ToString();
string height = tg.Get(PdfName.HEIGHT).ToString();
string bpp = tg.Get(PdfName.BITSPERCOMPONENT).ToString();
if (filter == "/FlateDecode")
{
bytes = PdfReader.FlateDecode(bytes, true);
System.Drawing.Imaging.PixelFormat pixelFormat;
switch (int.Parse(bpp))
{
case 1:
pixelFormat = System.Drawing.Imaging.PixelFormat.Format1bppIndexed;
break;
case 8:
pixelFormat = System.Drawing.Imaging.PixelFormat.Format8bppIndexed;
break;
case 24:
pixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
break;
default:
throw new Exception("Unknown pixel format " + bpp);
}
var bmp = new System.Drawing.Bitmap(Int32.Parse(width), Int32.Parse(height), pixelFormat);
System.Drawing.Imaging.BitmapData bmd = bmp.LockBits(new System.Drawing.Rectangle(0, 0, Int32.Parse(width),
Int32.Parse(height)), System.Drawing.Imaging.ImageLockMode.WriteOnly, pixelFormat);
Marshal.Copy(bytes, 0, bmd.Scan0, bytes.Length);
bmp.UnlockBits(bmd);
bmp.Save(@"C:\temp\my_flate_picture-" + DateTime.Now.Ticks.ToString() + ".png", ImageFormat.Png);
}
什麼我需要做什麼來讓自己的圖像提取的作品與FlateDecode
打交道時所需?
注意:我不想用另一個庫來提取圖像。我正在尋找一個解決方案,利用只有 iTextSharp和.NET FW。如果一個解決方案通過Java(iText)存在,並且很容易移植到.NET FW位,那麼這個位就足夠了。
UPDATE:ImageMask
屬性設置爲true,這意味着沒有顏色空間,因此隱含黑色和白色。在bpp進入1時,PixelFormat
應該是Format1bppIndexed
,如前所述,產生上面看到的嵌入式圖像。
UPDATE:要使用Acrobat X Pro將圖像大小提取出來,此特定示例的圖像大小列爲2403x3005。通過iTextSharp提取時,大小被列爲2544x3300。我在調試器中修改了鏡像大小,以鏡像2403x3005,但是在調用Marshal.Copy(bytes, 0, bmd.Scan0, bytes.Length);
時,我收到了一個異常。
試圖讀取或寫入受保護的內存。這通常是指示其他內存已損壞的 。
我的假設是,這是由於修改了大小,因此不再對應於正在使用的字節數據。
UPDATE:每Jimmy的建議,我已驗證主叫PdfReader.GetStreamBytes
返回一個字節[]長度等於寬度高度/ 8由於GetStreamBytes
應當調用FlateDecode
。手動調用FlateDecode
和調用PdfReader.GetStreamBytes
都生成了一個byte []長度爲1049401,而寬度爲 height/8爲2544 * 3300/8或1049400,因此存在差異1.不確定這是否是根本原因或不是,一個一個;但是,如果確實如此,我不確定如何解決。
UPDATE:在試圖通過kuujinbo提到的方法,我遇到了一個IndexOutOfRangeException
當我嘗試了RenderImage
監聽器中調用renderInfo.GetImage();
。在調用FlateDecode
時,前面所述的寬度*高度/ 8與字節[]長度相比是1的事實使我認爲這些都是相同的;然而,解決方案仍然沒有解決。
at System.util.zlib.Adler32.adler32(Int64 adler, Byte[] buf, Int32 index, Int32 len)
at System.util.zlib.ZStream.read_buf(Byte[] buf, Int32 start, Int32 size)
at System.util.zlib.Deflate.fill_window()
at System.util.zlib.Deflate.deflate_slow(Int32 flush)
at System.util.zlib.Deflate.deflate(ZStream strm, Int32 flush)
at System.util.zlib.ZStream.deflate(Int32 flush)
at System.util.zlib.ZDeflaterOutputStream.Write(Byte[] b, Int32 off, Int32 len)
at iTextSharp.text.pdf.codec.PngWriter.WriteData(Byte[] data, Int32 stride)
at iTextSharp.text.pdf.parser.PdfImageObject.DecodeImageBytes()
at iTextSharp.text.pdf.parser.PdfImageObject..ctor(PdfDictionary dictionary, Byte[] samples)
at iTextSharp.text.pdf.parser.PdfImageObject..ctor(PRStream stream)
at iTextSharp.text.pdf.parser.ImageRenderInfo.PrepareImageObject()
at iTextSharp.text.pdf.parser.ImageRenderInfo.GetImage()
at cyos.infrastructure.Core.MyImageRenderListener.RenderImage(ImageRenderInfo renderInfo)
UPDATE:試圖改變我原來的解決方案列在這裏,以及通過kuujinbo與PDF中的不同頁面所帶來的解決方案不同的方法產生的圖像;然而,當過濾器類型爲/FlateDecode
並且沒有爲給定實例生成圖像時,問題始終顯示。
圖像如何失真?你可以張貼截圖嗎?這聽起來像你在某個地方出現了錯誤,或者錯誤地將事情放大了。 – ChrisF 2011-12-13 17:35:52
@ChrisF剛剛添加了一個圖片 – 2011-12-13 17:38:07
這與這個問題有關嗎? HTTP://計算器。com/questions/757265/how-do-pdfs-bitspercomponent-translate-to-bits-per-pixel-for-images如果不是,我會盡量深入挖掘當我有機會 – 2011-12-13 19:32:34