用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,以及许多其他有趣的匹配项。