用iText读取图片签名stream/object..是黑色背景和白色前景,如何反转
With iText Reading an image signature stream/object..is black background and white foreground, how to reverse
我正在尝试从 PDF 文档中读取图像对象。图像以黑色背景和白色文本出现。我该如何扭转它。 pdf中的图像,是白色前景和黑色背景。
这是代码,加载图像组件的主要部分
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
public class MyImageRenderListener implements RenderListener {
/**
* The new document to which we've added a border rectangle.
*/
protected String path = "";
/**
* Creates a RenderListener that will look for images.
*/
public MyImageRenderListener(String path) {
this.path = path;
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
*/
public void beginTextBlock() {
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
*/
public void endTextBlock() {
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
*com.itextpdf.text.pdf.parser.ImageRenderInfo)
*/
public void renderImage(final ImageRenderInfo renderInfo) {
try {
String filename;
FileOutputStream os;
PdfImageObject image = renderInfo.getImage();
PdfImageObject tmp = null;
PdfName filter = (PdfName) image.get(PdfName.FILTER);
///
PdfDictionary imageDictionary = image.getDictionary();
// Try SMASK, SMASKINDATA
PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
// todo - required - black white - fix
PdfImageObject maskImage = new PdfImageObject(maskStream);
image = maskImage;
if (PdfName.DCTDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jpg");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JPXDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jp2");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JBIG2DECODE.equals(filter)) {
// ignore: filter not supported.
} else {
BufferedImage awtimage = renderInfo.getImage().getBufferedImage();
if (awtimage != null) {
filename = String.format(path, renderInfo.getRef().getNumber(), "png");
ImageIO.write(awtimage, "png", new FileOutputStream(filename));
}
}
try {
final String newfile = String.format(path, renderInfo.getRef().getNumber(), ".x.", "png");
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ImageIO.write(newBi, "png", new FileOutputStream(newfile));
} catch(final Exception e) {
e.printStackTrace();;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Image makeBlackAndWhitePng(PdfImageObject image) throws IOException, DocumentException {
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(newBi, "png", baos);
return Image.getInstance(baos.toByteArray());
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
*com.itextpdf.text.pdf.parser.TextRenderInfo)
*/
public void renderText(TextRenderInfo renderInfo) {
}
}
以及加载页面的代码
public static void readImages(final PdfReader reader, final File filex) throws IOException {
for (int i = 0; i < reader.getXrefSize(); i++) {
PdfObject pdfobj = reader.getPdfObject(i);
if (pdfobj == null || !pdfobj.isStream()) {
continue;
}
PdfStream stream = (PdfStream) pdfobj;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
byte[] img = PdfReader.getStreamBytesRaw((PRStream) stream);
FileOutputStream out = new FileOutputStream(new File(filex.getParentFile(), String.format("%1d", i) + ".jpg"));
out.write(img);
out.flush();
out.close();
}
}
}
结合我的意见:
你看到的,只是包含透明度信息的图像软蒙版,白色=不透明,黑色=透明。基本图像实际上是全黑的,但只有在蒙版指示不透明的地方,才会绘制黑色图像。因此它看起来像颠倒了。
您可以使用图像处理库来反转位图。只需在谷歌上搜索“imageio invert image”returns this, this,以及许多其他有趣的匹配项。
我正在尝试从 PDF 文档中读取图像对象。图像以黑色背景和白色文本出现。我该如何扭转它。 pdf中的图像,是白色前景和黑色背景。
这是代码,加载图像组件的主要部分
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
public class MyImageRenderListener implements RenderListener {
/**
* The new document to which we've added a border rectangle.
*/
protected String path = "";
/**
* Creates a RenderListener that will look for images.
*/
public MyImageRenderListener(String path) {
this.path = path;
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
*/
public void beginTextBlock() {
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
*/
public void endTextBlock() {
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
*com.itextpdf.text.pdf.parser.ImageRenderInfo)
*/
public void renderImage(final ImageRenderInfo renderInfo) {
try {
String filename;
FileOutputStream os;
PdfImageObject image = renderInfo.getImage();
PdfImageObject tmp = null;
PdfName filter = (PdfName) image.get(PdfName.FILTER);
///
PdfDictionary imageDictionary = image.getDictionary();
// Try SMASK, SMASKINDATA
PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
// todo - required - black white - fix
PdfImageObject maskImage = new PdfImageObject(maskStream);
image = maskImage;
if (PdfName.DCTDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jpg");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JPXDECODE.equals(filter)) {
filename = String.format(path, renderInfo.getRef().getNumber(), "jp2");
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} else if (PdfName.JBIG2DECODE.equals(filter)) {
// ignore: filter not supported.
} else {
BufferedImage awtimage = renderInfo.getImage().getBufferedImage();
if (awtimage != null) {
filename = String.format(path, renderInfo.getRef().getNumber(), "png");
ImageIO.write(awtimage, "png", new FileOutputStream(filename));
}
}
try {
final String newfile = String.format(path, renderInfo.getRef().getNumber(), ".x.", "png");
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ImageIO.write(newBi, "png", new FileOutputStream(newfile));
} catch(final Exception e) {
e.printStackTrace();;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Image makeBlackAndWhitePng(PdfImageObject image) throws IOException, DocumentException {
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(newBi, "png", baos);
return Image.getInstance(baos.toByteArray());
}
/**
* @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
*com.itextpdf.text.pdf.parser.TextRenderInfo)
*/
public void renderText(TextRenderInfo renderInfo) {
}
}
以及加载页面的代码
public static void readImages(final PdfReader reader, final File filex) throws IOException {
for (int i = 0; i < reader.getXrefSize(); i++) {
PdfObject pdfobj = reader.getPdfObject(i);
if (pdfobj == null || !pdfobj.isStream()) {
continue;
}
PdfStream stream = (PdfStream) pdfobj;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
byte[] img = PdfReader.getStreamBytesRaw((PRStream) stream);
FileOutputStream out = new FileOutputStream(new File(filex.getParentFile(), String.format("%1d", i) + ".jpg"));
out.write(img);
out.flush();
out.close();
}
}
}
结合我的意见:
你看到的,只是包含透明度信息的图像软蒙版,白色=不透明,黑色=透明。基本图像实际上是全黑的,但只有在蒙版指示不透明的地方,才会绘制黑色图像。因此它看起来像颠倒了。
您可以使用图像处理库来反转位图。只需在谷歌上搜索“imageio invert image”returns this, this,以及许多其他有趣的匹配项。