使用 Java 裁剪/修剪 JPG 文件的空白区域

发布于 2024-12-04 00:58:31 字数 621 浏览 1 评论 0原文

是否有一个框架能够删除图像的空白(矩形)。我们根据技术图纸创建图像缩略图,遗憾的是这些图纸是 PDF 格式。我们将 PDF 转换为 SVG,然后转换为 JPG。通常技术图纸都很小,现在放在缩略图的左上角:

+---------+----------------------+
|         |                      |
| (image) |                      |
|         |                      |
+---------+                      |
|                                |
|                                |
|                                |
|                                |
|              (empty space)     |
|                                |
|                                |
+--------------------------------+

那么如何轻松去除空白并缩小 JPG 文件呢?

Is there a framework which is able to remove the white space (rectangular) of an image. We create Image Thumbnails from technical drawings which are unfortunately in PDF format. We convert the PDF to SVG and then to JPG. Often the technical drawings are very small and now placed in the upper left corner of the thumbnail:

+---------+----------------------+
|         |                      |
| (image) |                      |
|         |                      |
+---------+                      |
|                                |
|                                |
|                                |
|                                |
|              (empty space)     |
|                                |
|                                |
+--------------------------------+

So how can I easily remove the empty space and shrink the JPG file?

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

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

发布评论

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

评论(3

淡写薰衣草的香 2024-12-11 00:58:31

它可以在 JAI 中完成,如此线程中所示。或者这是我刚刚编写的一些 Java 代码,可以用来执行此操作:

public class TrimWhite {
    private BufferedImage img;

    public TrimWhite(File input) {
        try {
            img = ImageIO.read(input);
        } catch (IOException e) {
            throw new RuntimeException( "Problem reading image", e );
        }
    }

    public void trim() {
        int width  = getTrimmedWidth();
        int height = getTrimmedHeight();

        BufferedImage newImg = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Graphics g = newImg.createGraphics();
        g.drawImage( img, 0, 0, null );
        img = newImg;
    }

    public void write(File f) {
        try {
            ImageIO.write(img, "bmp", f);
        } catch (IOException e) {
            throw new RuntimeException( "Problem writing image", e );
        }
    }

    private int getTrimmedWidth() {
        int height       = this.img.getHeight();
        int width        = this.img.getWidth();
        int trimmedWidth = 0;

        for(int i = 0; i < height; i++) {
            for(int j = width - 1; j >= 0; j--) {
                if(img.getRGB(j, i) != Color.WHITE.getRGB() &&
                        j > trimmedWidth) {
                    trimmedWidth = j;
                    break;
                }
            }
        }

        return trimmedWidth;
    }

    private int getTrimmedHeight() {
        int width         = this.img.getWidth();
        int height        = this.img.getHeight();
        int trimmedHeight = 0;

        for(int i = 0; i < width; i++) {
            for(int j = height - 1; j >= 0; j--) {
                if(img.getRGB(i, j) != Color.WHITE.getRGB() &&
                        j > trimmedHeight) {
                    trimmedHeight = j;
                    break;
                }
            }
        }

        return trimmedHeight;
    }

    public static void main(String[] args) {
        TrimWhite trim = new TrimWhite(new File("...\\someInput.bmp"));
        trim.trim();
        trim.write(new File("...\\someOutput.bmp"));
    }
}

It can be done in JAI as is demonstrated in this thread. Or here's some Java code I just wrote which can be used to do it:

public class TrimWhite {
    private BufferedImage img;

    public TrimWhite(File input) {
        try {
            img = ImageIO.read(input);
        } catch (IOException e) {
            throw new RuntimeException( "Problem reading image", e );
        }
    }

    public void trim() {
        int width  = getTrimmedWidth();
        int height = getTrimmedHeight();

        BufferedImage newImg = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Graphics g = newImg.createGraphics();
        g.drawImage( img, 0, 0, null );
        img = newImg;
    }

    public void write(File f) {
        try {
            ImageIO.write(img, "bmp", f);
        } catch (IOException e) {
            throw new RuntimeException( "Problem writing image", e );
        }
    }

    private int getTrimmedWidth() {
        int height       = this.img.getHeight();
        int width        = this.img.getWidth();
        int trimmedWidth = 0;

        for(int i = 0; i < height; i++) {
            for(int j = width - 1; j >= 0; j--) {
                if(img.getRGB(j, i) != Color.WHITE.getRGB() &&
                        j > trimmedWidth) {
                    trimmedWidth = j;
                    break;
                }
            }
        }

        return trimmedWidth;
    }

    private int getTrimmedHeight() {
        int width         = this.img.getWidth();
        int height        = this.img.getHeight();
        int trimmedHeight = 0;

        for(int i = 0; i < width; i++) {
            for(int j = height - 1; j >= 0; j--) {
                if(img.getRGB(i, j) != Color.WHITE.getRGB() &&
                        j > trimmedHeight) {
                    trimmedHeight = j;
                    break;
                }
            }
        }

        return trimmedHeight;
    }

    public static void main(String[] args) {
        TrimWhite trim = new TrimWhite(new File("...\\someInput.bmp"));
        trim.trim();
        trim.write(new File("...\\someOutput.bmp"));
    }
}
我还不会笑 2024-12-11 00:58:31

对于 Android 用户,这里是一个使用 Mike Kwan 的示例 答案:

    public static Bitmap TrimImage(Bitmap bmp) {
    int imgHeight = bmp.getHeight();
    int imgWidth  = bmp.getWidth();

    //TRIM WIDTH
    int widthStart  = imgWidth;
    int widthEnd = 0;
    for(int i = 0; i < imgHeight; i++) {
        for(int j = imgWidth - 1; j >= 0; j--) {
            if(bmp.getPixel(j, i) != Color.TRANSPARENT &&
                    j < widthStart) {
                widthStart = j;
            }
            if(bmp.getPixel(j, i) != Color.TRANSPARENT &&
                    j > widthEnd) {
                widthEnd = j;
                break;
            }
        }
    }
    //TRIM HEIGHT
    int heightStart = imgHeight;
    int heightEnd = 0;
    for(int i = 0; i < imgWidth; i++) {
        for(int j = imgHeight - 1; j >= 0; j--) {
            if(bmp.getPixel(i, j) != Color.TRANSPARENT &&
                    j < heightStart) {
                heightStart = j;
            }
            if(bmp.getPixel(i, j) != Color.TRANSPARENT &&
                    j > heightEnd) {
                heightEnd = j;
                break;
            }
        }
    }

    int finalWidth = widthEnd - widthStart;
    int finalHeight = heightEnd - heightStart;

    return Bitmap.createBitmap(bmp, widthStart,heightStart,finalWidth, finalHeight);
}

希望这对某人有帮助 :)

编辑:

伙计们,我刚刚更新了我的答案,因为最后的代码只是修剪图像的末尾,而不是开头。这个效果很好:)

For Android users, here is an example using Mike Kwan Answer:

    public static Bitmap TrimImage(Bitmap bmp) {
    int imgHeight = bmp.getHeight();
    int imgWidth  = bmp.getWidth();

    //TRIM WIDTH
    int widthStart  = imgWidth;
    int widthEnd = 0;
    for(int i = 0; i < imgHeight; i++) {
        for(int j = imgWidth - 1; j >= 0; j--) {
            if(bmp.getPixel(j, i) != Color.TRANSPARENT &&
                    j < widthStart) {
                widthStart = j;
            }
            if(bmp.getPixel(j, i) != Color.TRANSPARENT &&
                    j > widthEnd) {
                widthEnd = j;
                break;
            }
        }
    }
    //TRIM HEIGHT
    int heightStart = imgHeight;
    int heightEnd = 0;
    for(int i = 0; i < imgWidth; i++) {
        for(int j = imgHeight - 1; j >= 0; j--) {
            if(bmp.getPixel(i, j) != Color.TRANSPARENT &&
                    j < heightStart) {
                heightStart = j;
            }
            if(bmp.getPixel(i, j) != Color.TRANSPARENT &&
                    j > heightEnd) {
                heightEnd = j;
                break;
            }
        }
    }

    int finalWidth = widthEnd - widthStart;
    int finalHeight = heightEnd - heightStart;

    return Bitmap.createBitmap(bmp, widthStart,heightStart,finalWidth, finalHeight);
}

Hope this help someone :)

EDIT:

Guys, I just updated my answer cuz last code was just trimming the end of the image, not the beginning. This one is working just great :)

流心雨 2024-12-11 00:58:31

这是最快的。

public static Bitmap TrimBitmap(Bitmap bmp) {
    final int imgHeight = bmp.getHeight();
    final int imgWidth  = bmp.getWidth();

    //Take Data
    int[] pixels = new int[imgWidth * imgHeight];
    bmp.getPixels(pixels, 0, imgWidth, 0, 0, imgWidth, imgHeight);
    int[] horizontalData=new int[imgHeight],verticalData=new int[imgWidth];
    int num=0;
    for (int pixel:pixels){
        horizontalData[num/imgWidth]|=pixel;
        verticalData[num%imgWidth]|=pixel;
        num++;
    }


    


    //TRIM WIDTH - RIGHT
    int endWidth  = imgWidth;
    for(int x = imgWidth - 1; x >= 0; x--) {
        int data = verticalData[x];
        if ((data>>24)!=0)
            break;
        endWidth--;
    }



    


    //TRIM HEIGHT - BOTTOM
    int endHeight = imgHeight;
    for(int x = imgHeight - 1; x >= 0; x--) {
        int data =horizontalData[x];
        if ((data>>24)!=0)
            break;
        endHeight--;
    }


    return Bitmap.createBitmap(
            bmp,
            0,
            0,
            endWidth,
            endHeight
    );

}

This is the fastest.

public static Bitmap TrimBitmap(Bitmap bmp) {
    final int imgHeight = bmp.getHeight();
    final int imgWidth  = bmp.getWidth();

    //Take Data
    int[] pixels = new int[imgWidth * imgHeight];
    bmp.getPixels(pixels, 0, imgWidth, 0, 0, imgWidth, imgHeight);
    int[] horizontalData=new int[imgHeight],verticalData=new int[imgWidth];
    int num=0;
    for (int pixel:pixels){
        horizontalData[num/imgWidth]|=pixel;
        verticalData[num%imgWidth]|=pixel;
        num++;
    }


    


    //TRIM WIDTH - RIGHT
    int endWidth  = imgWidth;
    for(int x = imgWidth - 1; x >= 0; x--) {
        int data = verticalData[x];
        if ((data>>24)!=0)
            break;
        endWidth--;
    }



    


    //TRIM HEIGHT - BOTTOM
    int endHeight = imgHeight;
    for(int x = imgHeight - 1; x >= 0; x--) {
        int data =horizontalData[x];
        if ((data>>24)!=0)
            break;
        endHeight--;
    }


    return Bitmap.createBitmap(
            bmp,
            0,
            0,
            endWidth,
            endHeight
    );

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