调整位图大小而不会降低质量

时间:2012-07-20 08:18:51

标签: android

我将图片从SD卡加载到位图。文件是jpeg。我是这样做的:

Bitmap b = BitmapFactory.decodeFile("/sdcard/DinEgen/"+name.get(position), null);
        Bitmap img = Bitmap.createScaledBitmap( b, width, height, true);

         b.recycle();
        i.setImageBitmap(img);

但是当我scaledBitmap我失去了质量。当我只使用“位图b”时质量很好。因此,当我使用createScaledBitmap时,我正在失去信心。如何将位图b缩放到hightwidth变量的大小?

3 个答案:

答案 0 :(得分:1)

我为它写了一堂课。

   public class BitmapSizeHelper
{

    public static enum ScalingLogic
        {
            CROP, FIT
        }

    public static Bitmap getBitmapFromResources(Resources res, int resId, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            Options options = new 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 getBitmapFromPath(int targetW, int targetH, String photopath, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {

            Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(photopath, options);
            options.inJustDecodeBounds = false;
            options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight, scalingLogic);
            Bitmap bitmap = BitmapFactory.decodeFile(photopath, options);

            return bitmap;

        }

    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 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(), Config.ARGB_8888);
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

            return scaledBitmap;
        }

    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 :(得分:0)

除非图像vector graphics,否则无法在不失去质量的情况下调整图像大小。可能有办法尽量减少质量损失。

答案 2 :(得分:-2)

解码JPEG时,请使用BitmapOptions明确告诉不要缩放等。

Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap b = BitmapFactory.decodeFile("/sdcard/DinEgen/"+name.get(position), options);