【问题标题】:Crop white spaces from images从图像中裁剪空白
【发布时间】:2018-05-15 02:49:19
【问题描述】:

我有一项服务可以下载图像并使用 picasso 在 CardView 中显示它。

Picasso.with(context).load(beer.getLabelLarge()).fit().centerCrop().into(imgBeerLabel);

但是这些图像带有不受欢迎的空白:

我想修剪这些图像并仅显示标签,不显示白色边框,并将其调整为 ImageView 尺寸。

-- 编辑

白色部分的大小可变。

这个问题和这个问题报告的一样:

https://stackoverflow.com/questions/12175991/crop-image-white-space-automatically-using-jquery

但是用很多代码解决了这个问题,我现在想避免。

一种可能对我有帮助的解决方案是关注图像中的特定正方形并放大该部分,使其填满整个屏幕,而不管白色部分的大小。

预期的结果是:

有没有办法使用毕加索和转换来做到这一点?

【问题讨论】:

标签: android image-processing picasso android-image android-bitmap


【解决方案1】:

我最终基于this library 中的代码创建了一个新的 Transform 实现。

它在垂直和水平方向的两侧寻找第一个不同的像素,并从那里裁剪位图。它并不完美,但它适合我的需求。

public class CropMiddleFirstPixelTransformation implements Transformation {
    private int mWidth;
    private int mHeight;


    @Override
    public Bitmap transform(Bitmap source) {
        int width = source.getWidth();
        int height = source.getHeight();

        int[] horizontalMiddleArray = new int[width];
        source.getPixels(horizontalMiddleArray, 0, width, 0, height / 2, width, 1);

        int[] verticalMiddleArray = new int[height];
        source.getPixels(verticalMiddleArray, 0, 1, width / 2, 0, 1, height);

        int left = getFirstNonWhitePosition(horizontalMiddleArray);
        int right = getLastNonWhitePosition(horizontalMiddleArray);

        int top = getFirstNonWhitePosition(verticalMiddleArray);
        int bottom = getLastNonWhitePosition(verticalMiddleArray);

        mWidth = right - left;
        mHeight = bottom - top;


        if (!isNegative(left, right, top, bottom)) {
            return source;
        }

        Bitmap bitmap = Bitmap.createBitmap(source, left, top, mWidth , mHeight);
        source.recycle();
        return bitmap;

    }

    private boolean isNegative(int... values) {
        for (int i : values) {
            if (i < 0) {
                return false;
            }
        }
        return true;

    }

    private int getFirstNonWhitePosition(int[] horizontalMiddleArray) {
        int left = 0;
        for (int i = 0; i < horizontalMiddleArray.length; i++) {
            if (i == 0) {
                left = horizontalMiddleArray[i];
            }
            if (left != horizontalMiddleArray[i]) {
                return i;
            }
        }
        return -1;
    }

    private int getLastNonWhitePosition(int[] horizontalMiddleArray) {
        int right = 0;
        int length = horizontalMiddleArray.length;
        for (int i = length - 1; i > 0; i--) {
            if (i == length - 1) {
                right = horizontalMiddleArray[i];
            }
            if (right != horizontalMiddleArray[i]) {
                return i;
            }
        }
        return -1;
    }


    @Override
    public String key() {
        return "CropMiddleFirstPixelTransformation(width=" + mWidth + ", height=" + mHeight + ")";
    }
}

【讨论】:

  • 如果所有值都是正数,您的 isNegative 方法似乎返回 true。这是故意的吗?我相信如果图像外部有合法的白色像素(例如橙色和白色的 Kronos 徽标),这也可能会意外裁剪图像。
【解决方案2】:

使用矢量图像或九块图像的概念。下面给出了网址

对于矢量图像:- https://developer.android.com/studio/write/vector-asset-studio.html

for NinePatch 图片https://developer.android.com/studio/write/draw9patch.html

【讨论】:

  • 我不明白如何以动态方式使用它。你能提供更多信息吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 2019-10-31
  • 2012-08-23
相关资源
最近更新 更多