如何在 Java 中将图像相互叠加?

发布于 2024-07-14 20:34:33 字数 2127 浏览 12 评论 0原文

所以我一直在发帖,但还没有得到可靠的答案:

我已经创建了一个图像调整大小类,带有裁剪方法。 裁剪效果很好。 我遇到的问题是我在 GraphicsdrawImage 函数中指定的背景颜色无法正常工作。 无论我提供什么,它都默认为黑色作为背景(在本例中为Color.WHITE)。

此外,覆盖图像或最上面的图像(来自文件)正在被反转(我认为是)或以其他方式变色。 为了让您可以更好地概念化这一点,我采用了一个 jpeg 并将其覆盖在新的 BufferedImage 之上,新的缓冲图像的背景未设置。 下面是我正在使用的代码:

public void Crop(int Height, int Width, int SourceX, int SourceY) throws Exception {
    //output height and width
    int OutputWidth = this.OutputImage.getWidth();
    int OutputHeight = this.OutputImage.getHeight();

    //create output streams
    ByteArrayOutputStream MyByteArrayOutputStream = new ByteArrayOutputStream();
    MemoryCacheImageOutputStream MyMemoryCacheImageOutputStream = new MemoryCacheImageOutputStream(MyByteArrayOutputStream);

    //Create a new  BufferedImage
    BufferedImage NewImage = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
    Graphics MyGraphics = NewImage.createGraphics();

    MyGraphics.drawImage(this.OutputImage, -SourceX, -SourceY, OutputWidth, OutputHeight, Color.WHITE, null);

    // Get Writer and set compression
    Iterator MyIterator = ImageIO.getImageWritersByFormatName("png");
    if (MyIterator.hasNext()) {
        //get image writer
        ImageWriter MyImageWriter = (ImageWriter)MyIterator.next();

        //get params
        ImageWriteParam MyImageWriteParam = MyImageWriter.getDefaultWriteParam();

        //set outputstream
        MyImageWriter.setOutput(MyMemoryCacheImageOutputStream);

        //create new ioimage
        IIOImage MyIIOImage = new IIOImage(NewImage, null, null);

        //write new image
        MyImageWriter.write(null, MyIIOImage, MyImageWriteParam);
    }

    //convert output stream back to inputstream
    ByteArrayInputStream MyByteArrayInputStream = new ByteArrayInputStream(MyByteArrayOutputStream.toByteArray());
    MemoryCacheImageInputStream MyMemoryCacheImageInputStream = new MemoryCacheImageInputStream(MyByteArrayInputStream);

    //resassign as a buffered image
    this.OutputImage = ImageIO.read(MyMemoryCacheImageInputStream);
}

So I have been posting all over and have yet to get a solid answer:

I have created an image resizing class, with a crop method. The cropping works great. The issue that I am having is the background color that I specify in the drawImage function of Graphics is not working correctly. It defaults to black as the background regardless of what I supply (in this case Color.WHITE).

Also, the overlaying image or top most image (comes from a file) is being inverted (I think it is) or otherwise discolored. Just so you can conceptualize this a little bit better, I am taking a jpeg and overlaying it on top of a new BufferedImage, the new buffered image's background is not being set. Here is the code below that I am working with:

public void Crop(int Height, int Width, int SourceX, int SourceY) throws Exception {
    //output height and width
    int OutputWidth = this.OutputImage.getWidth();
    int OutputHeight = this.OutputImage.getHeight();

    //create output streams
    ByteArrayOutputStream MyByteArrayOutputStream = new ByteArrayOutputStream();
    MemoryCacheImageOutputStream MyMemoryCacheImageOutputStream = new MemoryCacheImageOutputStream(MyByteArrayOutputStream);

    //Create a new  BufferedImage
    BufferedImage NewImage = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
    Graphics MyGraphics = NewImage.createGraphics();

    MyGraphics.drawImage(this.OutputImage, -SourceX, -SourceY, OutputWidth, OutputHeight, Color.WHITE, null);

    // Get Writer and set compression
    Iterator MyIterator = ImageIO.getImageWritersByFormatName("png");
    if (MyIterator.hasNext()) {
        //get image writer
        ImageWriter MyImageWriter = (ImageWriter)MyIterator.next();

        //get params
        ImageWriteParam MyImageWriteParam = MyImageWriter.getDefaultWriteParam();

        //set outputstream
        MyImageWriter.setOutput(MyMemoryCacheImageOutputStream);

        //create new ioimage
        IIOImage MyIIOImage = new IIOImage(NewImage, null, null);

        //write new image
        MyImageWriter.write(null, MyIIOImage, MyImageWriteParam);
    }

    //convert output stream back to inputstream
    ByteArrayInputStream MyByteArrayInputStream = new ByteArrayInputStream(MyByteArrayOutputStream.toByteArray());
    MemoryCacheImageInputStream MyMemoryCacheImageInputStream = new MemoryCacheImageInputStream(MyByteArrayInputStream);

    //resassign as a buffered image
    this.OutputImage = ImageIO.read(MyMemoryCacheImageInputStream);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七婞 2024-07-21 20:34:33

您能否确定是 Graphics 方法还是 ImageIO 方法破坏了您的图像? 看来您可以通过短路整个 ImageIO 过程并简单地分配来测试这一点,

this.OutputImage = NewImage;

就这一点而言,我认为 ImageIO 操作可以获得一些东西? 在编写示例时,它看起来(理想情况下)是无操作的。

另外,在开始 ImageIO 过程之前,不要处置 Graphics2D。 它通常没有什么区别,但你不想假设这一点。

Can you isolate whether it's the Graphics methods or the ImageIO methods that are mangling your image? It looks like you could test this by short-circuiting the entire ImageIO process and simply assigning

this.OutputImage = NewImage;

For that matter, I assume there's something gained by the ImageIO operations? As the sample is written, it appears to be (ideally) a no-op.

Also, you don't dispose your Graphics2D before you begin the ImageIO process. It often doesn't make a difference, but you don't want to assume that.

左岸枫 2024-07-21 20:34:33

关于叠加颜色失真问题,请确保您的图形上下文处于绘画模式而不是异或模式。 (Graphics.setPaintMode())。 否则,颜色位将被异或在一起。

On the overlay color distortion problem, make sure your graphics context is in paint mode and not xor mode. (Graphics.setPaintMode()). Otherwise the color bits are XOR'd together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文