Trying to scale down a Bitmap in Android not working

99封情书 提交于 2019-12-10 03:49:20

问题


I'm trying to scale down a bitmap. In short, the image is originally from a ByteArray with a width of 4016. After I scale the image down with factory options, it still reports the image with a width of 4016.

Here are two clips of my code:

Bitmap myBitmap = null;
        @Override
        protected byte[] doInBackground(Object... params) {


            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;

            if (options.outHeight > options.outWidth) {
                options.inSampleSize = calculateInSampleSize(options, 640, 960);
            } else {
                options.inSampleSize = calculateInSampleSize(options, 960, 640);
            }

            options.inJustDecodeBounds = false;

            //myImageByteArray is 4016 wide
            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);

            //This log statement outputs 4016!!! Shouldn't it be smaller since I just decoded the byteArray with options?
            Log.d("bitmap", myBitmap.getWidth()+"");

}

        public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;

            if (height > reqHeight || width > reqWidth) {

                // Calculate ratios of height and width to requested height and
                // width
                final int heightRatio = Math.round((float) height / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);

                // Choose the smallest ratio as inSampleSize value, this will
                // guarantee
                // a final image with both dimensions larger than or equal to
                // the
                // requested height and width.
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }

            return inSampleSize;
        }

Update:

Here are two clips of my code:

Bitmap myBitmap = null;
        @Override
        protected byte[] doInBackground(Object... params) {


            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            //myImageByteArray is 4016 wide
            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);
            if (options.outHeight > options.outWidth) {
                options.inSampleSize = calculateInSampleSize(options, 640, 960);
            } else {
                options.inSampleSize = calculateInSampleSize(options, 960, 640);
            }

            options.inJustDecodeBounds = false;

            //myImageByteArray is 4016 wide
            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);

            //This log statement outputs around 1000 now. 
            Log.d("bitmap", myBitmap.getWidth()+"");

}

        public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;

            if (height > reqHeight || width > reqWidth) {

                // Calculate ratios of height and width to requested height and
                // width
                final int heightRatio = Math.round((float) height / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);

                // Choose the smallest ratio as inSampleSize value, this will
                // guarantee
                // a final image with both dimensions larger than or equal to
                // the
                // requested height and width.
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }

            return inSampleSize;
        }

回答1:


You need to call .decodeByteArray(..) twice! Once to attain the width and the height with .inJustDecodeBounds set to true and then again with .inSampleSize to get the actual scaled Bitmap, options.outHeight and options.outWidth in your code are probably zero.

call BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options); before checking outHeight and outWidth.

Edit

Take a look at this example from Google's Android Dev site:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;

Notice that options.outHeight is used after calling decodeResources(...). This you have to fix in your code.




回答2:


you didn't fill the bitmapOptions with anything that will set its "outHeight" and "outWidth".

you should check out the bitmap tutorials of google:

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

in order to decide what is the value to scale to, you need to know the size of the image compared to the destination size. that's why you need to do decoding twice.

btw, there is another way to downsample images, as i've shown here.



来源:https://stackoverflow.com/questions/21032840/trying-to-scale-down-a-bitmap-in-android-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!