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」のみを使用すると、品質は良好です。そのため、使用するとクォリティーが失われますcreateScaledBitmaphightビットマップ b をサイズからwidth変数にスケーリングするにはどうすればよいですか?

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 に答える