在 iTextSharp 中将 System.Drawing.Image 映射到正确的 PdfName.COLORSPACE 和 PdfName.FILTER
Map System.Drawing.Image to proper PdfName.COLORSPACE and PdfName.FILTER in iTextSharp
我正在使用 iTextSharp 更新 PDF 中修改后的图像对象 System.Drawing.Image。如何根据 System.Drawing.Image 正确设置 PdfName.COLORSPACE 和 PdfName.FILTER?我不确定哪些 System.Drawing.Image 属性可用于映射。
private void SetImageData(PdfImageObject pdfImage, System.Drawing.Image image, byte[] imageData)
{
PRStream imgStream = (PRStream)pdfImage.GetDictionary();
imgStream.Clear();
imgStream.SetData(imageData, false, PRStream.NO_COMPRESSION);
imgStream.Put(PdfName.TYPE, PdfName.XOBJECT);
imgStream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
imgStream.Put(PdfName.WIDTH, new PdfNumber(image.Width));
imgStream.Put(PdfName.HEIGHT, new PdfNumber(image.Height));
imgStream.Put(PdfName.LENGTH, new PdfNumber(imageData.LongLength));
// Not sure how to properly set these entries based on the image properties
imgStream.Put(PdfName.BITSPERCOMPONENT, 8);
imgStream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
imgStream.Put(PdfName.FILTER, PdfName.DCTDECODE);
}
我采纳了 Chris Haas 的建议,通过将 System.Drawing.Image 写入临时 PDF,然后将其作为 PdfImageObject 读回。
using (MemoryStream ms = new MemoryStream())
{
using (iTextSharp.text.Document doc = new iTextSharp.text.Document())
{
using (iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc))
{
doc.Open();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(drawingImage, drawingImage.RawFormat);
image.SimplifyColorspace();
doc.Add(image);
doc.Close();
}
}
... code that opens the mem stream with PdfReader and retrieves the image as PdfImageObj...
}
这行得通,但似乎有点像作弊。我在对 doc.Add(image)
的调用中逐步执行代码,发现最终从 iTextSharp.text.Image 对象创建了一个 PdfImage 对象,并且 PdfImage 对象包含我需要的所有字典条目。所以我决定在原来的作弊上偷工减料,并提出这个作为我的最终解决方案:
private void SetImageData(PdfImageObject pdfImageObj, byte[] imageData)
{
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imageData);
image.SimplifyColorSpace();
PdfImage tempPdfImage = new PdfImage(image, "TempImg", null);
PRStream imgStream = (PRStream)pdfImageObj.GetDictionary();
imgStream.Clear();
imgStream.SetDataRaw(imageData);
imgStream.Merge(tempPdfImage);
}
我正在使用 iTextSharp 更新 PDF 中修改后的图像对象 System.Drawing.Image。如何根据 System.Drawing.Image 正确设置 PdfName.COLORSPACE 和 PdfName.FILTER?我不确定哪些 System.Drawing.Image 属性可用于映射。
private void SetImageData(PdfImageObject pdfImage, System.Drawing.Image image, byte[] imageData)
{
PRStream imgStream = (PRStream)pdfImage.GetDictionary();
imgStream.Clear();
imgStream.SetData(imageData, false, PRStream.NO_COMPRESSION);
imgStream.Put(PdfName.TYPE, PdfName.XOBJECT);
imgStream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
imgStream.Put(PdfName.WIDTH, new PdfNumber(image.Width));
imgStream.Put(PdfName.HEIGHT, new PdfNumber(image.Height));
imgStream.Put(PdfName.LENGTH, new PdfNumber(imageData.LongLength));
// Not sure how to properly set these entries based on the image properties
imgStream.Put(PdfName.BITSPERCOMPONENT, 8);
imgStream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
imgStream.Put(PdfName.FILTER, PdfName.DCTDECODE);
}
我采纳了 Chris Haas 的建议,通过将 System.Drawing.Image 写入临时 PDF,然后将其作为 PdfImageObject 读回。
using (MemoryStream ms = new MemoryStream())
{
using (iTextSharp.text.Document doc = new iTextSharp.text.Document())
{
using (iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc))
{
doc.Open();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(drawingImage, drawingImage.RawFormat);
image.SimplifyColorspace();
doc.Add(image);
doc.Close();
}
}
... code that opens the mem stream with PdfReader and retrieves the image as PdfImageObj...
}
这行得通,但似乎有点像作弊。我在对 doc.Add(image)
的调用中逐步执行代码,发现最终从 iTextSharp.text.Image 对象创建了一个 PdfImage 对象,并且 PdfImage 对象包含我需要的所有字典条目。所以我决定在原来的作弊上偷工减料,并提出这个作为我的最终解决方案:
private void SetImageData(PdfImageObject pdfImageObj, byte[] imageData)
{
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imageData);
image.SimplifyColorSpace();
PdfImage tempPdfImage = new PdfImage(image, "TempImg", null);
PRStream imgStream = (PRStream)pdfImageObj.GetDictionary();
imgStream.Clear();
imgStream.SetDataRaw(imageData);
imgStream.Merge(tempPdfImage);
}