图片是安卓中很难处理的一个环节,所以想写一篇关于图片处理的文章总结下开发中遇到的问题。
首先是图片上传,本人的手机是小米 note 照相机拍摄的一张照片大约在3.5M到5.8M不等,显然不对图片处理是不行的,第一 上传的太慢,要是用户选择了十张照片估计要半天。第二 把这张图片转化成Bitmap显示 肯定是要OOM的 所以就需要对图片处理,
第一步:
* 压缩到指定比例
*
* @param path
* @return
*/
public static Bitmap parseBitmapToSize(String path, int reqWidth) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//不占用内存加载图片
BitmapFactory.decodeFile(path, options);
int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;
int inSampleSize = 1;
if (bitmapHeight > reqWidth || bitmapWidth > reqWidth) {
if (bitmapWidth > bitmapHeight) {
inSampleSize = Math.round((float) bitmapHeight / (float) reqWidth);
} else {
inSampleSize = Math.round((float) bitmapWidth / (float) reqWidth);
}
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
return bitmap;
}
相信很多人都能明白这段代码是什么意思。到这一步还没有结束因为得到的图片还是很大,这一步只是把图片缩小到指定比例 比如一张3120*4208的照片缩小到1280*1280 这里的大小还是在1M以上,所以还需要继续处理接下来就是具体的缩放了 然后就是保存到 内存中,代码如下:
/**
* 写图片文件到SD卡 并且压缩
*
* @throws IOException
*/
public static String saveImageToSD(Bitmap source, int quality, int bitmapOutSize) {
FileOutputStream fos = null;
ByteArrayOutputStream stream = null;
Bitmap thumb = null;
try {
if (source != null) {
String filePath = ImageUtil.setCameraImgPath(SoftApplication.softApplication);
fos = new FileOutputStream(filePath);
stream = new ByteArrayOutputStream();
int with = source.getWidth();//图片的宽
int height = source.getHeight();//图片的高
int max = with > height ? with : height;
if (max > bitmapOutSize) {
//缩放
Matrix matrix = new Matrix();
float scale = bitmapOutSize * 1f / max;
matrix.setScale(scale, scale);
thumb = Bitmap.createBitmap(source, 0, 0, with, height, matrix, true);
thumb.compress(Bitmap.CompressFormat.JPEG, quality, stream);
} else {
source.compress(Bitmap.CompressFormat.JPEG, 100, stream);
}
byte[] bytes = stream.toByteArray();
fos.write(bytes);
fos.flush();
return filePath;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (!source.isRecycled()) {
source.recycle();
}
if (thumb != null && thumb.isRecycled()) {
thumb.recycle();
}
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
这里的缩放用到了Matrix
这个类就是对图片进行缩放处理的,具体使用可以参考MediaStore
这歌类我也是从这里类里面找的源码自己改的
这个类里面有保存图片到到数据库并且生成一个缩略图,代码如下
/**
* Insert an image and create a thumbnail for it.
*
* @param cr The content resolver to use
* @param imagePath The path to the image to insert
* @param name The name of the image
* @param description The description of the image
* @return The URL to the newly created image
* @throws FileNotFoundException
*/
public static final String insertImage(ContentResolver cr, String imagePath,
String name, String description) throws FileNotFoundException {
// Check if file exists with a FileInputStream
FileInputStream stream = new FileInputStream(imagePath);
try {
Bitmap bm = BitmapFactory.decodeFile(imagePath);
String ret = insertImage(cr, bm, name, description);
bm.recycle();
return ret;
} finally {
try {
stream.close();
} catch (IOException e) {
}
}
}
从注解就能明白这个方法的意思很好理解
这个方法里会调用
private static final Bitmap StoreThumbnail(
ContentResolver cr,
Bitmap source,
long id,
float width, float height,
int kind) {
// create the matrix to scale it
Matrix matrix = new Matrix();
float scaleX = width / source.getWidth();
float scaleY = height / source.getHeight();
matrix.setScale(scaleX, scaleY);
Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
source.getWidth(),
source.getHeight(), matrix,
true);
ContentValues values = new ContentValues(4);
values.put(Images.Thumbnails.KIND, kind);
values.put(Images.Thumbnails.IMAGE_ID, (int)id);
values.put(Images.Thumbnails.HEIGHT, thumb.getHeight());
values.put(Images.Thumbnails.WIDTH, thumb.getWidth());
Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
try {
OutputStream thumbOut = cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
thumbOut.close();
return thumb;
}
catch (FileNotFoundException ex) {
return null;
}
catch (IOException ex) {
return null;
}
}
这里就是处理图片成缩略图然后保存的,所以对于图片的处理完全可以参考MediaStore
这个类。
最后拿到图片压缩后保存的路径再得到流上传到服务器就行了。
这里有个问题:就是在图片缩放的时候就会出现一些特殊情况:比如图片很长很长,但是却很窄 导致图片被缩放成一条细线了。不过网上有解决方案 随便搜搜就找到了。
如果你有什么其他比较好的方案可以推荐给我~ 多谢 QQ:391573665