版权声明:本文为“剑西”原创文章,转载需注明出处! https://blog.csdn.net/mabeijianxi/article/details/82085890
请尊重原创,转载请注明出处: https://blog.csdn.net/mabeijianxi/article/details/82085890
不管是 Android、iOS、PC都可能需要面临一些图片处理的时候。
笔者遇到了一个截图的,在屏幕里只截出3D渲染的那层 layer ,比如背景绘制的是摄像头采集是数据,前景是我们用引擎渲染的一些3D模型,我们现在需要截出这些3D模型,由于一些原因(主要是实时计算的性能),我们截出来的图片会带一圈透明边框。于是我们需要把起裁剪掉。可以在手机上实时裁,也可以在PC上脚本裁剪。
实现思路
解码出图片,得到 rgba 的像素数据。分四次遍历。左、上、右、下。去找第一个带有色彩的像素位置。我们知道全透明其16阿尔法通道的值就是0,或者说其实这个像素值就是。于是我们只是找到左上右下第一个非0的点的位置即可。知道四个方向的边界位置,只需要剪裁下即可得到目标数据。
代码实现
提供 Android 与 Python两种实现
Android:
public void crop(Bitmap sourceBitmap,File saveFile) throws IOException {
int sourceHeight = sourceBitmap.getHeight();
int sourceWidth = sourceBitmap.getWidth();
int[] pixels = new int[sourceHeight * sourceWidth];
sourceBitmap.getPixels(pixels, 0, sourceWidth, 0, 0, sourceWidth, sourceHeight);
int top = 0;
int bot = sourceHeight;
int left = 0;
int right = sourceWidth;
a:
for (int i = 0; i < sourceHeight; i++) {
for (int j = 0; j < sourceWidth; j++) {
int color = pixels[i * sourceWidth + j];
if (color != 0) {
top = i;
break a;
}
}
}
b:
for (int i = sourceHeight - 1; i >= 0; i--) {
for (int j = 0; j < sourceWidth; j++) {
int color = pixels[i * sourceWidth + j];
if (color != 0) {
bot = i;
break b;
}
}
}
c:
for (int i = 0; i < sourceWidth; i++) {
for (int j = 0; j < sourceHeight; j++) {
int color = pixels[j * sourceWidth + i];
if (color != 0) {
left = i;
break c;
}
}
}
d:
for (int i = sourceWidth - 1; i >= 0; i--) {
for (int j = 0; j < sourceHeight; j++) {
int color = pixels[j * sourceWidth + i];
if (color != 0) {
right = i;
break d;
}
}
}
int realWidth = right - left;
int realHeight = bot - top;
int[] realColors = new int[realWidth * realHeight];
sourceBitmap.getPixels(realColors, 0, realWidth, left, top, realWidth, realHeight);
sourceBitmap.recycle();
Bitmap bitmap = Bitmap.createBitmap(realColors, realWidth, realHeight, Bitmap.Config.ARGB_8888);
FileOutputStream fileOutputStream = new FileOutputStream(saveFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
bitmap.recycle();
fileOutputStream.close();
}
Python:
#
# Generated by jianxi([email protected])
# Created by jianxi.
# DateTime: 2018/8/26 下午3:50
#
import sys
import os
from PIL import Image
from PIL import ImageChops
inFileHome = sys.argv[1]
outFileHome = sys.argv[2]
def crop(parentFile,fileName):
image = Image.open(parentFile+'/' +fileName)
red, green, blue, alpha = image.split()
print(alpha)
width = image.size[0]
height = image.size[1]
print (width)
print (height)
def getTop():
for i in range(height):
for j in range(width):
color = alpha.getpixel((j,i))
if not color==0:
top = i
return i
def getBot():
for i in range(height-1,-1,-1):
print (i)
for j in range(width):
color = alpha.getpixel((j,i))
if not color==0:
bot = i
return i
def getLeft():
for i in range(width):
for j in range(height):
color = alpha.getpixel((i,j))
if not color==0:
left = i
return i
def getRight():
for i in range(width-1,-1,-1):
for j in range(height):
color = alpha.getpixel((i,j))
if not color==0:
right = i
return i
left = getLeft()
top = getTop()
right = getRight()
bot = getBot()
if not left:
left = 0
if not top:
top = 0
if not right:
right = width
if not bot:
bot = height
print (left)
print (top)
print (right)
print (bot)
rect = (left,top,right,bot)
print (rect)
new_image = image.crop(rect)
new_image.save(outFileHome+"/"+fileName,"PNG")
for root,dirs,files in os.walk(inFileHome):
for file in files:
if os.path.splitext(file)[1] == ".png":
crop(inFileHome,file)
python 这个输入是两个参数,第一个是需要处理的文件夹。第二个参数是保存处理好的文件的文件夹。