簡體   English   中英

旋轉BufferedImage並去除黑邊

[英]Rotate BufferedImage and remove black bound

我有原始圖片:

在此處輸入圖片說明

我使用以下Java代碼旋轉圖像:

BufferedImage bi = ImageHelper.rotateImage(bi, -imageSkewAngle);

ImageIO.write(bi, "PNG", new File("out.png"));

結果,我得到以下圖像:

在此處輸入圖片說明

如何刪除圖像周圍的黑色邊框,並使其成為適當的白色矩形,並且不占用太多空間..僅使用所需的大小進行轉換...等於原始尺寸,如果需要,可以更大?

下面的程序包含一個方法rotateImage ,該方法應該與問題中使用的rotateImage方法等效:它計算旋轉圖像的邊界,創建具有所需大小的新圖像,並將原始圖像繪制到圖像的中心。新的一個。

該方法還接收用於確定背景顏色的Color backgroundColor 在示例中,將其設置為Color.RED ,以說明效果。

該示例還包含一個方法rotateImageInPlace 此方法將始終創建與輸入圖像具有相同大小的圖像,並且還將(旋轉的)原始圖像繪制到該圖像的中心。

該程序創建兩個面板,左一個示出的結果rotateImage和右之一的結果rotateImageInPlace ,條件是允許改變的旋轉角度的滑塊一起。 因此,該程序的輸出如下所示:

rotateImageInPlace

(同樣, Color.RED僅用於說明。為您的應用程序將其更改為Color.WHITE

正如評論中所討論的,根據圖像的內容和旋轉角度,不改變圖像大小的目標可能並不總是可以實現的。 因此,對於某些角度,旋轉后的圖像可能不適合生成的圖像。 但是對於問題的用例來說,應該可以:用例是原始圖像已經包含一個旋轉的矩形“關注區域”。 因此,未出現在輸出中的部分通常應該是輸入圖像中不包含任何相關信息的部分。

(否則,有必要提供有關輸入圖像結構,邊框大小或旋轉角度的更多信息,或者必須通過逐像素檢查圖像來手動找出所需的大小,看看哪些像素是黑色的,哪些像素是白色的)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;

public class RotateImageWithoutBorder
{
    public static void main(String[] args) throws Exception
    {
        BufferedImage image = 
            ImageIO.read(new URL("https://i.stack.imgur.com/tMtFh.png"));


        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ImagePanel imagePanel0 = new ImagePanel();
        imagePanel0.setBackground(Color.BLUE);

        ImagePanel imagePanel1 = new ImagePanel();
        imagePanel1.setBackground(Color.BLUE);

        JSlider slider = new JSlider(0, 100, 1);
        slider.addChangeListener(e -> 
        {
            double alpha = slider.getValue() / 100.0;
            double angleRad = alpha * Math.PI * 2;

            BufferedImage rotatedImage = rotateImage(
                image, angleRad, Color.RED);
            imagePanel0.setImage(rotatedImage);

            BufferedImage rotatedImageInPlace = rotateImageInPlace(
                image, angleRad, Color.RED);
            imagePanel1.setImage(rotatedImageInPlace);

            f.repaint();
        });
        slider.setValue(0);
        f.getContentPane().add(slider, BorderLayout.SOUTH);

        JPanel imagePanels = new JPanel(new GridLayout(1,2));
        imagePanels.add(imagePanel0);
        imagePanels.add(imagePanel1);
        f.getContentPane().add(imagePanels, BorderLayout.CENTER);

        f.setSize(800,500);
        f.setLocationRelativeTo(null);
        f.setVisible(true);

    }

    private static BufferedImage rotateImage(
        BufferedImage image, double angleRad, Color backgroundColor)
    {
        int w = image.getWidth();
        int h = image.getHeight();
        AffineTransform at = AffineTransform.getRotateInstance(
            angleRad, w * 0.5, h * 0.5);
        Rectangle rotatedBounds = at.createTransformedShape(
            new Rectangle(0, 0, w, h)).getBounds();
        BufferedImage result = new BufferedImage(
            rotatedBounds.width, rotatedBounds.height, 
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = result.createGraphics();
        g.setColor(backgroundColor);
        g.fillRect(0, 0, rotatedBounds.width, rotatedBounds.height);
        at.preConcatenate(AffineTransform.getTranslateInstance(
            -rotatedBounds.x, -rotatedBounds.y));
        g.transform(at);
        g.setRenderingHint(
            RenderingHints.KEY_INTERPOLATION, 
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return result;        
    }

    private static BufferedImage rotateImageInPlace(
        BufferedImage image, double angleRad, Color backgroundColor)
    {
        int w = image.getWidth();
        int h = image.getHeight();
        AffineTransform at = AffineTransform.getRotateInstance(
            angleRad, w * 0.5, h * 0.5);
        Rectangle rotatedBounds = at.createTransformedShape(
            new Rectangle(0, 0, w, h)).getBounds();
        BufferedImage result = new BufferedImage(
            w, h, 
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = result.createGraphics();
        g.setColor(backgroundColor);
        g.fillRect(0, 0, w, h);
        at.preConcatenate(AffineTransform.getTranslateInstance(
            -rotatedBounds.x - (rotatedBounds.width - w) * 0.5, 
            -rotatedBounds.y - (rotatedBounds.height - h) * 0.5));
        g.transform(at);
        g.setRenderingHint(
            RenderingHints.KEY_INTERPOLATION, 
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return result;        
    }


    static class ImagePanel extends JPanel
    {
        private BufferedImage image;

        public void setImage(BufferedImage image)
        {
            this.image = image;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            if (image != null)
            {
                g.drawImage(image, 0, 0, null);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM