【问题标题】:How to retain original color of Image on rotation using java如何使用java在旋转时保留图像的原始颜色
【发布时间】:2017-12-05 07:09:27
【问题描述】:

我有一个接收图像文件的 java 应用程序。我想使用 exif 信息来旋转它们。

在 StackOverflow 上,我发现了两种不同的方法,在这两种情况下,我都从 BufferedImage 开始:

        BufferedImage image=ImageIO.read(sourceFile.getInputStream());

第一个解决方案来自this post

        ImageTransformer.ImageInformation imageInformation=ImageTransformer.readImageInformation(sourceFile.getInputStream());
        AffineTransform tranform=ImageTransformer.getExifTransformation(imageInformation);
        image=ImageTransformer.transformImage(image,tranform);

这里的一些帖子也推荐了第二个,使用 Thumbnailator:

BufferedImage image = Thumbnails.of(sourceFile.getInputStream()).scale(1).asBufferedImage();

两种方式都可以正确旋转我的图像。而且这两种解决方案都会改变颜色,这是我不想要的。我将附上两个文件,“白色”一个是旋转错误的原始文件。当我注释掉两个轮换代码时,这正是我所实现的。

另一个,红色的,是旋转正确但颜色错误的那个。

如何通过改变旋转来获得原始颜色?

【问题讨论】:

  • Windows 资源管理器是否正确旋转图像?
  • 是的。但是我在 C# 客户端中使用的 webbrowser 组件没有。我正在对图像进行 OCR,这也需要固定旋转。
  • 我会试试这个。您知道如何为缩略图变体解决此问题吗?因为这是我更喜欢的一个。由于红色图像,我只使用了另一个:/
  • AffineTransformOp.TYPE_NEAREST_NEIGHBOR 这可以通过一种方法解决。我仍然会欣赏一个较短的解决方案;)

标签: java image exif


【解决方案1】:

我遇到了同样的问题,事实证明您不应该将一种格式转换为另一种格式(BufferedImage 转换为 ByteArrayOutputStream,反之亦然)。如果您有字节数组 - 使用 ByteArrayOutputStream 和 ByteArrayInputStream。

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ByteArrayInputStream in = new ByteArrayInputStream(file.getContents());
    Thumbnails.of(in)
        .size(2000,1500)
        .toOutputStream(baos);
    byte[] bytes = baos.toByteArray();

【讨论】:

  • 我最后做了什么,只是将 tesseract PageSegmentationMode 设置为 tesseract.setPageSegMode(ITessAPI.TessPageSegMode.PSM_AUTO_OSD);这种方式 tesseract 完全处理预处理。
【解决方案2】:

我一直试图将图像的中心与框架的中心对齐,但我没有找到一个好的方法,但我设法在不丢失其属性的情况下旋转图像:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class Rotate extends JComponent {
    // Attributes
    private String route = null;
    private double degree = 0.0;

    // Constructor
    public Rotate(String route, double degree) {
        this.setRoute(route);
        this.setDegree(degree);
    }

    // Create a bufferedImage for the given route
    private BufferedImage getBufferedImage() {
        Image image = null;
        try {
            image = ImageIO.read(new File(getRoute()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return (BufferedImage) image;
    }

    // Paint the image
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(getDegree()));
        g2.setTransform(at);
        // Here I tried to calculate you must add the coordenates to start
        // drawing the image in your frame
        g2.drawImage(getBufferedImage(), 0, 0, null);
    }

    public double getDiagonal() {
        return Math.hypot(getBufferedImage().getWidth(), getBufferedImage().getHeight());
    }

    public String getRoute() {
        return route;
    }

    public void setRoute(String route) {
        this.route = route;
    }

    public double getDegree() {
        return degree;
    }

    public void setDegree(double degree) {
        this.degree = degree;
    }

}

为了测试它:

import java.awt.Container;

import javax.swing.JFrame;

public class ImageRotation {

    public static void main(String[] args) {
        // The route of the image and the degrees of rotation
        String route = "C:\\Users\\Public\\Pictures\\Sample Pictures\\download.jpg";
        double degrees = 30;
        // Frame to display the image
        JFrame jf = new JFrame("Image Rotated");
        // Introduce the route and degrees
        Rotate tl = new Rotate(route, degrees);
        // Set the size of the frame
        int hyp = (int) tl.getDiagonal();
        jf.setSize(hyp, hyp);
        // Print the rotated image in the frame
        Container cp = jf.getContentPane();
        cp.add(tl);
        // Display
        jf.setVisible(true);
    }
}

【讨论】:

  • 如果有人能告诉我如何联系这两个中心,我将不胜感激,我一直在寻找和尝试,但我没有找到方法。
  • 是的,但这不是使用 exif - 用户可以随时改变主意,不是吗!!??!!
猜你喜欢
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 2013-02-23
  • 1970-01-01
  • 2021-01-18
相关资源
最近更新 更多