Rug*_*ggs 1 java image crop image-processing
我有一个精灵表,每个图像都以32x32单元为中心.实际图像不是32x32,而是略小.我想做的是拍摄一个单元格并裁剪透明像素,使图像尽可能小.
我将如何在Java(JDK 6)中做到这一点?
以下是我目前如何将瓷砖表拆分为单元格的示例:
BufferedImage tilesheet = ImageIO.read(getClass().getResourceAsStream("/sheet.png");
for (int i = 0; i < 15; i++) {
Image img = tilesheet.getSubimage(i * 32, 0, 32, 32);
// crop here..
}
Run Code Online (Sandbox Code Playgroud)
我目前的想法是测试中心的每个像素,看看它是否透明,但我想知道是否会有更快/更清洁的方法.
有一个简单的解决方案 - 扫描每个像素.该算法具有恒定的性能 O(w•h).
private static BufferedImage trimImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
int top = height / 2;
int bottom = top;
int left = width / 2 ;
int right = left;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (image.getRGB(x, y) != 0){
top = Math.min(top, x);
bottom = Math.max(bottom, x);
left = Math.min(left, x);
right = Math.max(right, x);
}
}
}
return image.getSubimage(left, top, right - left, bottom - top);
}
Run Code Online (Sandbox Code Playgroud)
但这更有效:
private static BufferedImage trimImage(BufferedImage image) {
WritableRaster raster = image.getAlphaRaster();
int width = raster.getWidth();
int height = raster.getHeight();
int left = 0;
int top = 0;
int right = width - 1;
int bottom = height - 1;
int minRight = width - 1;
int minBottom = height - 1;
top:
for (;top < bottom; top++){
for (int x = 0; x < width; x++){
if (raster.getSample(x, top, 0) != 0){
minRight = x;
minBottom = top;
break top;
}
}
}
left:
for (;left < minRight; left++){
for (int y = height - 1; y > top; y--){
if (raster.getSample(left, y, 0) != 0){
minBottom = y;
break left;
}
}
}
bottom:
for (;bottom > minBottom; bottom--){
for (int x = width - 1; x >= left; x--){
if (raster.getSample(x, bottom, 0) != 0){
minRight = x;
break bottom;
}
}
}
right:
for (;right > minRight; right--){
for (int y = bottom; y >= top; y--){
if (raster.getSample(right, y, 0) != 0){
break right;
}
}
}
return image.getSubimage(left, top, right - left + 1, bottom - top + 1);
}
Run Code Online (Sandbox Code Playgroud)
该算法遵循pepan的答案(见上文),并且效率提高2到4倍.不同之处在于:它从不扫描任何像素两次,并尝试在每个阶段收缩搜索范围.
方法在最坏情况下的表现是 O(w•h–a•b)
| 归档时间: |
|
| 查看次数: |
5371 次 |
| 最近记录: |