2010年4月7日星期三

利用 Java 以不同形狀剪裁圖像 (Use Java to cut a shape of area from an image)

import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;

public static BufferedImage cutEllipse(BufferedImage source, int x, int y, int width, int height, int cx, int cy, Color color){
    BufferedImage out = new BufferedImage(width, height, source.getType());
    Graphics2D g2d = out.createGraphics();
    g2d.setColor(color);
    g2d.fillRect(0, 0, width, height);
    g2d.dispose();
    Ellipse2D.Float ellipse = new Ellipse2D.Float(x -= cx, y -= cx, width, height);
    for (int i = 0; i < source.getWidth(); i++){
        for (int j = 0; j < source.getHeight(); j++){
            if (ellipse.contains(i, j)){
                out.setRGB(i - x - 1, j - y - 1, source.getRGB(i, j));
            }
        }
    }
    return out;
}

public static BufferedImage cutEllipse(BufferedImage source, int x, int y, int width, int height){
    return cutEllipse(source, x, y, width, height, 0, 0, Color.WHITE);
}

public static BufferedImage cutPolygon(BufferedImage source, Polygon polygon, Color color){
    Rectangle rectangle = polygon.getBounds();
    BufferedImage out = new BufferedImage(rectangle.width, rectangle.height, source.getType());
    Graphics2D g2d = out.createGraphics();
    g2d.setColor(color);
    g2d.fillRect(0, 0, rectangle.width, rectangle.height);
    g2d.dispose();
    for (int i = 0; i < source.getWidth(); i++){
        for (int j = 0; j < source.getHeight(); j++){
            if (polygon.contains(i, j)){
                out.setRGB(i - rectangle.x, j - rectangle.y, source.getRGB(i, j));
            }
        }
    }
    return out;
}

修改前
before
apple.jpg

以 cutEllipse(source, 150, 150, 200, 200, 100, 100, Color.GREEN) 修改後
edit with cutEllipse(source, 150, 150, 200, 200, 100, 100, Color.GREEN)
apple2.jpg

以 cutPolygon(source, new Polygon(new int[]{150, 50, 150, 250}, new int[]{50, 150, 250, 150}, 4), Color.BLUE) 修改後
edit with cutPolygon(source, new Polygon(new int[]{150, 50, 150, 250}, new int[]{50, 150, 250, 150}, 4), Color.BLUE)
apple3.jpg

同樣可以利用 final int RECTANGLE = 0, final int ELLIPSE = 1, final int POLYGON = 2 這方式
來編制 cut(BufferedImage, int, ...) 的統一性及處理

必須承認的是這兩種剪裁非矩形的圖形時效果不太好, 處理速度亦慢, 而且所剪裁的圖像也並非十分完美
但對於應急狀況下也不妨一試
若有更佳的處理方法請告知

沒有留言 :

發佈留言