在Android中对大图片进行缩放真的很不尽如人意,不知道是不是我的方法不对。下面我列出3种对图片缩放的方法,并给出相应速度。请高人指教。
第一种是BitmapFactory和BitmapFactory.Options。
首先,BitmapFactory.Options有几个Fields很有用:
inJustDecodeBounds:If set to true, the decoder will return null (no bitmap), but the out...
也就是说,当inJustDecodeBounds设成true时,bitmap并不加载到内存,这样效率很高哦。而这时,你可以获得bitmap的高、宽等信息。
outHeight:The resulting height of the bitmap, set independent of the state of inJustDecodeBounds.
outWidth:The resulting width of the bitmap, set independent of the state of inJustDecodeBounds.
看到了吧,上面3个变量是相关联的哦。
inSampleSize :
If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.
这就是用来做缩放比的。这里有个技巧:
inSampleSize=(outHeight/Height+outWidth/Width)/2
实践证明,这样缩放出来的图片还是很好的。
最后用BitmapFactory.decodeFile(path, options)生成。
由于只是对bitmap加载到内存一次,所以效率比较高。解析速度快。
第二种是使用Bitmap加Matrix来缩放。
ThumbnailUtils源码:
首先要获得原bitmap,再从原bitmap的基础上生成新图片。这样效率很低。
第三种是用2.2新加的类ThumbnailUtils来做。 让我们新看看这个类,从API中来看,此类就三个静态方法:createVideoThumbnail、extractThumbnail(Bitmap source, int width, int height, int options)、extractThumbnail(Bitmap source, int width, int height)。 我这里使用了第三个方法。再看看它的源码,下面会附上。是上面我们用到的BitmapFactory.Options和Matrix等经过人家一阵加工而成。 效率好像比第二种方法高一点点。
下面是我的例子:
- package com.linc.ResolvePicture;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Matrix;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.media.ThumbnailUtils;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class ResolvePicture extends Activity {
- private static String tag="ResolvePicture";
- Drawable bmImg;
- ImageView imView;
- ImageView imView2;
- TextView text;
- String theTime;
- long start, stop;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- text=(TextView)findViewById(R.id.text);
- imView=(ImageView) findViewById(R.id.imageShow);
- imView2=(ImageView) findViewById(R.id.image2);
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.pic);
- start=System.currentTimeMillis();
- // imView.setImageDrawable(resizeImage(bitmap, 300, 100));
- imView2.setImageDrawable(resizeImage2("/sdcard/2.jpeg", 200, 100));
- stop=System.currentTimeMillis();
- String theTime= String.format("\n1 iterative: (%d msec)",
- stop - start);
- start=System.currentTimeMillis();
- imView.setImageBitmap(ThumbnailUtils.extractThumbnail(bitmap,200,100));//2.2才加进来的新类,简单易用
- // imView.setImageDrawable(resizeImage(bitmap, 30, 30));
- stop=System.currentTimeMillis();
- theTime+= String.format("\n2 iterative: (%d msec)",
- stop - start);
- text.setText(theTime);
- }
- //使用Bitmap加Matrix来缩放
- public static Drawable resizeImage(Bitmap bitmap, int w, int h)
- {
- Bitmap BitmapOrg = bitmap;
- int width = BitmapOrg.getWidth();
- int height = BitmapOrg.getHeight();
- int newWidth = w;
- int newHeight = h;
- float scaleWidth = ((float) newWidth) / width;
- float scaleHeight = ((float) newHeight) / height;
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
- // if you want to rotate the Bitmap
- // matrix.postRotate(45);
- Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
- height, matrix, true);
- return new BitmapDrawable(resizedBitmap);
- }
- //使用BitmapFactory.Options的inSampleSize参数来缩放
- public static Drawable resizeImage2(String path,
- int width,int height)
- {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;//不加载bitmap到内存中
- BitmapFactory.decodeFile(path,options);
- int outWidth = options.outWidth;
- int outHeight = options.outHeight;
- options.inDither = false;
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- options.inSampleSize = 1;
- if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0)
- {
- int sampleSize=(outWidth/width+outHeight/height)/2;
- Log.d(tag, "sampleSize = " + sampleSize);
- options.inSampleSize = sampleSize;
- }
- options.inJustDecodeBounds = false;
- return new BitmapDrawable(BitmapFactory.decodeFile(path, options));
- }
- //图片保存
- private void saveThePicture(Bitmap bitmap)
- {
- File file=new File("/sdcard/2.jpeg");
- try
- {
- FileOutputStream fos=new FileOutputStream(file);
- if(bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos))
- {
- fos.flush();
- fos.close();
- }
- }
- catch(FileNotFoundException e1)
- {
- e1.printStackTrace();
- }
- catch(IOException e2)
- {
- e2.printStackTrace();
- }
- }
- }
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package android.media;
- import android.content.ContentResolver;
- import android.content.ContentUris;
- import android.content.ContentValues;
- import android.database.Cursor;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.graphics.Rect;
- import android.media.MediaMetadataRetriever;
- import android.media.MediaFile.MediaFileType;
- import android.net.Uri;
- import android.os.ParcelFileDescriptor;
- import android.provider.BaseColumns;
- import android.provider.MediaStore.Images;
- import android.provider.MediaStore.Images.Thumbnails;
- import android.util.Log;
- import java.io.FileInputStream;
- import java.io.FileDescriptor;
- import java.io.IOException;
- import java.io.OutputStream;
- /**
- * Thumbnail generation routines for media provider.
- */
- public class ThumbnailUtils {
- private static final String TAG = "ThumbnailUtils";
- /* Maximum pixels size for created bitmap. */
- private static final int MAX_NUM_PIXELS_THUMBNAIL = 512 * 384;
- private static final int MAX_NUM_PIXELS_MICRO_THUMBNAIL = 128 * 128;
- private static final int UNCONSTRAINED = -1;
- /* Options used internally. */
- private static final int OPTIONS_NONE = 0x0;
- private static final int OPTIONS_SCALE_UP = 0x1;
- /**
- * Constant used to indicate we should recycle the input in
- * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
- */
- public static final int OPTIONS_RECYCLE_INPUT = 0x2;
- /**
- * Constant used to indicate the dimension of mini thumbnail.
- * @hide Only used by media framework and media provider internally.
- */
- public static final int TARGET_SIZE_MINI_THUMBNAIL = 320;
- /**
- * Constant used to indicate the dimension of micro thumbnail.
- * @hide Only used by media framework and media provider internally.
- */
- public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
- /**
- * This method first examines if the thumbnail embedded in EXIF is bigger than our target
- * size. If not, then it'll create a thumbnail from original image. Due to efficiency
- * consideration, we want to let MediaThumbRequest avoid calling this method twice for
- * both kinds, so it only requests for MICRO_KIND and set saveImage to true.
- *
- * This method always returns a "square thumbnail" for MICRO_KIND thumbnail.
- *
- * @param filePath the path of image file
- * @param kind could be MINI_KIND or MICRO_KIND
- * @return Bitmap
- *
- * @hide This method is only used by media framework and media provider internally.
- */
- public static Bitmap createImageThumbnail(String filePath, int kind) {
- boolean wantMini = (kind == Images.Thumbnails.MINI_KIND);
- int targetSize = wantMini
- ? TARGET_SIZE_MINI_THUMBNAIL
- : TARGET_SIZE_MICRO_THUMBNAIL;
- int maxPixels = wantMini
- ? MAX_NUM_PIXELS_THUMBNAIL
- : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
- SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
- Bitmap bitmap = null;
- MediaFileType fileType = MediaFile.getFileType(filePath);
- if (fileType != null && fileType.fileType == MediaFile.FILE_TYPE_JPEG) {
- createThumbnailFromEXIF(filePath, targetSize, maxPixels, sizedThumbnailBitmap);
- bitmap = sizedThumbnailBitmap.mBitmap;
- }
- if (bitmap == null) {
- try {
- FileDescriptor fd = new FileInputStream(filePath).getFD();
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = 1;
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFileDescriptor(fd, null, options);
- if (options.mCancel || options.outWidth == -1
- || options.outHeight == -1) {
- return null;
- }
- options.inSampleSize = computeSampleSize(
- options, targetSize, maxPixels);
- options.inJustDecodeBounds = false;
- options.inDither = false;
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
- } catch (IOException ex) {
- Log.e(TAG, "", ex);
- }
- }
- if (kind == Images.Thumbnails.MICRO_KIND) {
- // now we make it a "square thumbnail" for MICRO_KIND thumbnail
- bitmap = extractThumbnail(bitmap,
- TARGET_SIZE_MICRO_THUMBNAIL,
- TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);
- }
- return bitmap;
- }
- /**
- * Create a video thumbnail for a video. May return null if the video is
- * corrupt or the format is not supported.
- *
- * @param filePath the path of video file
- * @param kind could be MINI_KIND or MICRO_KIND
- */
- public static Bitmap createVideoThumbnail(String filePath, int kind) {
- Bitmap bitmap = null;
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- try {
- retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
- retriever.setDataSource(filePath);
- bitmap = retriever.captureFrame();
- } catch (IllegalArgumentException ex) {
- // Assume this is a corrupt video file
- } catch (RuntimeException ex) {
- // Assume this is a corrupt video file.
- } finally {
- try {
- retriever.release();
- } catch (RuntimeException ex) {
- // Ignore failures while cleaning up.
- }
- }
- if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
- bitmap = extractThumbnail(bitmap,
- TARGET_SIZE_MICRO_THUMBNAIL,
- TARGET_SIZE_MICRO_THUMBNAIL,
- OPTIONS_RECYCLE_INPUT);
- }
- return bitmap;
- }
- /**
- * Creates a centered bitmap of the desired size.
- *
- * @param source original bitmap source
- * @param width targeted width
- * @param height targeted height
- */
- public static Bitmap extractThumbnail(
- Bitmap source, int width, int height) {
- return extractThumbnail(source, width, height, OPTIONS_NONE);
- }
- /**
- * Creates a centered bitmap of the desired size.
- *
- * @param source original bitmap source
- * @param width targeted width
- * @param height targeted height
- * @param options options used during thumbnail extraction
- */
- public static Bitmap extractThumbnail(
- Bitmap source, int width, int height, int options) {
- if (source == null) {
- return null;
- }
- float scale;
- if (source.getWidth()
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?
立即登录/注册


微信扫码登录