0

我将图片从 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变量?

4

3 回答 3

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);
                }
        }

}`
于 2012-07-20T08:20:29.423 回答
0

除非它们是矢量图形,否则您无法在不损失质量的情况下调整图像大小。不过,可能有一些方法可以最大限度地减少质量损失。

于 2012-07-20T08:26:24.950 回答
-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);
于 2013-08-12T16:44:53.290 回答