Android: изменение размера drawable

Я работаю над приложением для android, и я хочу уменьшить свои иконки.
Я пробовал разные способы, но каждый раз возвращаемый drawable имеет низкую плотность..
Однако, когда я изменяю размер того же изображения в photoshop, он сохраняет хорошую плотность.
Следующий код является лучшим, что я нашел.

Не могли бы вы помочь мне улучшить его, пожалуйста ?

 public class MainActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ImageView newImage = (ImageView) findViewById(R.id.image);

    Bitmap unscaledBitmap = decodeResource(getBaseContext().getResources(),R.drawable.test2, 120, 120, ScalingLogic.FIT);

            newImage.setImageBitmap(createScaledBitmap(unscaledBitmap, 120, 120, ScalingLogic.FIT));
    newImage.setImageBitmap(createScaledBitmap(unscaledBitmap, 120, 120, ScalingLogic.FIT));



}

public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
        ScalingLogic scalingLogic) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight, scalingLogic);
        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        return unscaledBitmap;
    }


    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
    ScalingLogic scalingLogic) {
        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
                Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }


    public static enum ScalingLogic {
        CROP, FIT
    }


    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
    ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcWidth / dstWidth;
            } else {
                return srcHeight / dstHeight;
            }
        } else {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcHeight / dstHeight;
            } else {
                return srcWidth / dstWidth;
            }
        }
    }


    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
    ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.CROP) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                final int srcRectWidth = (int)(srcHeight * dstAspect);
                final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
            } else {
                final int srcRectHeight = (int)(srcWidth / dstAspect);
                final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
                return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
            }
        } else {
            return new Rect(0, 0, srcWidth, srcHeight);
        }
    }


    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
    ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
            } else {
                return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
            }
        } else {
            return new Rect(0, 0, dstWidth, dstHeight);
        }
    }

    }

1 ответ

  1. я думаю, что вам нужно использовать 9-патч изображений, где вы будете определены растяжимой области. Эти области определяются в специальной границе шириной 1 пиксель вокруг области, потому что пользовательские нарисованные кнопки могут выглядеть искаженными и пиксельными, когда их границы растягиваются в дополнение к остальной части изображения с другой стороны 9-патч изображения масштабируются отдельно. Это удобно для мобильных устройств, которые имеют меньшие экраны с различным разрешением и соотношением сторон. Взгляните на этот пример