【问题标题】:Android bilinear image downscalingAndroid双线性图像缩小
【发布时间】:2014-04-21 09:57:51
【问题描述】:

我正在尝试使用双线性过滤来缩小位图,但显然我的代码有问题,因为图像似乎比最近邻或仅使用 android 的下采样更好,但不如 Image Magick 的双耳过滤器好。

你发现我的调整大小方法有什么问题吗?

private Bitmap resize(Bitmap immutable, int reqWidth, int reqHeight) {
    Bitmap bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Config.ARGB_8888);
    float scaleFactor = immutable.getHeight() / (float) reqHeight;
    for (int x = 1; x < reqWidth - 1; x++) {
        for (int y = 1; y < reqHeight - 1; y++) {
            float sx = x * scaleFactor;
            float sy = y * scaleFactor;
            int rx = (int) (x * scaleFactor);
            int ry = (int) (y * scaleFactor);

            final int tl = immutable.getPixel(rx, ry);
            final int tr = immutable.getPixel(rx + 1, ry);
            final int bl = immutable.getPixel(rx, ry+1 );
            final int br = immutable.getPixel(rx + 1, ry+1);

            float xC1 = sx- rx;
            float xC2 = 2-xC1;

            float yC1 = sy - ry;
            float yC2 = 2 - yC1;

            xC1/=2;
            xC2/=2;
            yC1/=2;
            yC2/=2;

            final float firstAlpha = (Color.alpha(tl) * xC2 + Color.alpha(tr) * xC1);
            final float firstRed = (Color.red(tl) * xC2 + Color.red(tr) * xC1);
            final float firstBlue = (Color.blue(tl) * xC2 + Color.blue(tr) * xC1);
            final float firstGreen = (Color.green(tl) * xC2 + Color.green(tr) * xC1);

            final float secondAlpha = (Color.alpha(bl) * xC2 + Color.alpha(br) * xC1);
            final float secondRed = (Color.red(bl) * xC2 + Color.red(br) * xC1);
            final float secondGreen = (Color.green(bl) * xC2 + Color.green(br) * xC1);
            final float secondBlue = (Color.blue(bl) * xC2 + Color.blue(br) * xC1);

            int finalColor = Color.argb((int) (yC2 * firstAlpha + yC1 * secondAlpha), (int) (yC2 * firstRed + yC1 * secondRed), (int) (yC2 * firstGreen + yC1
                    * secondGreen), (int) (yC2 * firstBlue + yC1 * secondBlue));
            bitmap.setPixel(x, y, finalColor);
        }
    }

    return bitmap;
}

而 Image magick 的结果是这样的:

【问题讨论】:

    标签: android bitmap filtering interpolation


    【解决方案1】:

    Android 在调用 BitmapFactory.Options::inSampleSize->BitmapFactory.decodeResource() 时使用双线性缩小算法。

    如此好的缩减算法(不是最近邻)只包含 2 个步骤(加上计算输入/输出矩形裁剪的精确 Rect):

    1. 使用 BitmapFactory.Options::inSampleSize->BitmapFactory.decodeResource() 尽可能接近您需要的分辨率,但不能低于它
    2. 使用 Canvas::drawBitmap() 稍微缩小一点以达到精确的分辨率

    这里是索尼移动如何解决这个任务的详细解释:http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

    这里是SonyMobile scale utils的源代码:http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/

    【讨论】:

      猜你喜欢
      • 2018-09-27
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-20
      相关资源
      最近更新 更多