剪裁图片透明边界

请尊重原创,转载请注明出处: 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(mabeijianxi@gmail.com)
# 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 这个输入是两个参数,第一个是需要处理的文件夹。第二个参数是保存处理好的文件的文件夹。

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值