调整大小的图片,同时还美元的Android p $ pserving质量 [英] Resizing pictures while still preserving quality in android
问题描述
我想减少低于100 KB的图像文件的大小,而preserving图像质量例如WhatsApp和Facebook一样。
我试过几乎所有的$ C $ Android的形象融为一体pression的C语言中的计算器,但这并不为我工作。
现在我下面的这个博客缩小图像大小,我得到低于100 KB的图像,但图像质量较差。
有什么办法,我可以减少低于100 KB,而图片大小
preserving质量? (原始图像大小可以变化从20 KB至8 MB)
块引用>我试过JAI库的Java项目,而且它的工作好。
我可以用JAI库在android系统,以减少图像的大小???
块引用>先谢谢了。
来源$ C $ C到COM preSS图像:
进口java.io.ByteArrayOutputStream中;
进口的java.io.File;
进口java.io.FileNotFoundException;
进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口java.math.BigInteger的;
进口java.text.SimpleDateFormat的;
进口java.util.Date;
进口java.util.Locale中;进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.graphics.Canvas;
进口android.graphics.Matrix;
进口android.graphics.Paint;
进口android.media.ExifInterface;
进口android.os.Environment;
进口android.util.Log;公共类的COM $ P $ {pssBitmap 私人字符串路径;
公众的COM pressBitmap(字符串路径){
this.path =路径;
} 公共ByteArrayOutputStream getBitmap(){
ByteArrayOutputStream outStream =新ByteArrayOutputStream();
getscaledImage(路径).COM preSS(Bitmap.Com pressFormat.JPEG,100,outStream);
返回outStream;
} 公共ByteArrayOutputStream getBitmap(INT质量){
ByteArrayOutputStream outStream =新ByteArrayOutputStream();
getscaledImage(路径).COM preSS(Bitmap.Com pressFormat.JPEG,质量,outStream);
返回outStream;
} 公共字符串getComressFile(){
FileOutputStream中走出= NULL;
字符串文件名= createImageFile();
尝试{
OUT =新的FileOutputStream(文件名);
getscaledImage(路径).COM preSS(Bitmap.Com pressFormat.JPEG,80出);
}赶上(FileNotFoundException异常五){
e.printStackTrace();
}
档案文件=新的文件(文件名);
Log.e(长度,图像大小+ file.length());
返回的文件名;
} 私人位图getscaledImage(字符串文件路径){
位图scaledBitmap = NULL; BitmapFactory.Options选项=新BitmapFactory.Options();
options.inJustDe codeBounds = TRUE;
BMP位图= BitmapFactory.de codeFILE(文件路径,期权); INT的ActualHeight = options.outHeight;
INT ActualWidth的= options.outWidth;
浮了maxHeight = 800.0f;
浮了maxWidth = 600.0f;
浮imgRatio = ActualWidth的/的ActualHeight;
浮maxRatio =了maxWidth /了maxHeight; Log.v(图片,缩放宽度和高度都是之前+ ActualWidth的+ - +的ActualHeight); 如果(的ActualHeight>了maxHeight || ActualWidth的>了maxWidth){
如果(imgRatio< maxRatio){
imgRatio =了maxHeight /的ActualHeight;
ActualWidth的=(INT)(imgRatio * ActualWidth的);
的ActualHeight =(INT)了maxHeight;
}否则如果(imgRatio> maxRatio){
imgRatio =了maxWidth / ActualWidth的;
的ActualHeight =(INT)(imgRatio *的ActualHeight);
ActualWidth的=(INT)了maxWidth;
}其他{
的ActualHeight =(INT)了maxHeight;
ActualWidth的=(INT)了maxWidth;
}
} options.inSampleSize = calculateInSampleSize(选项,ActualWidth的,的ActualHeight);
options.inJustDe codeBounds = FALSE;
options.inDither = FALSE;
options.inPurgeable = TRUE;
options.inInputShareable = TRUE;
options.inTempStorage =新的字节[16 * 1024]; 尝试{
BMP = BitmapFactory.de codeFILE(文件路径,期权);
}
赶上(例外的OutOfMemoryError){
exception.printStackTrace(); }
尝试{
scaledBitmap = Bitmap.createBitmap(ActualWidth的,的ActualHeight,Bitmap.Config.ARGB_8888);
}
赶上(例外的OutOfMemoryError){
exception.printStackTrace();
} 浮ratioX = ActualWidth的/(浮点)options.outWidth;
浮ratioY =的ActualHeight /(浮点)options.outHeight;
浮middleX = ActualWidth的/ 2.0F;
浮middleY =的ActualHeight / 2.0F; 矩阵scaleMatrix =新的Matrix();
scaleMatrix.setScale(ratioX,ratioY,middleX,middleY); 帆布帆布=新的Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(BMP,middleX - bmp.getWidth()/ 2,middleY - bmp.getHeight()/ 2,新油漆(Paint.FILTER_BITMAP_FLAG)); Log.v(图片,缩放后的宽度和高度都是+ scaledBitmap.getWidth()+ - + scaledBitmap.getHeight()); ExifInterface EXIF;
尝试{
EXIF =新ExifInterface(文件路径); INT方向= exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,0);
Log.d(EXIF,的Exif:+方向);
字模=新的Matrix();
如果(方向== 6){
matrix.postRotate(90);
Log.d(EXIF,的Exif:+方向);
}否则如果(取向== 3){
matrix.postRotate(180);
Log.d(EXIF,的Exif:+方向);
}否则如果(方向== 8){
matrix.postRotate(270);
Log.d(EXIF,的Exif:+方向);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap,0,0,scaledBitmap.getWidth(),scaledBitmap.getHeight(),矩阵,真);
}赶上(IOException异常五){
e.printStackTrace();
} 返回scaledBitmap;
} 私人字符串createImageFile(){
。字符串的timeStamp =新的SimpleDateFormat(YYYYMMDD_HHMMSS,Locale.getDefault())格式(新的Date());
字符串映像文件名称=JPEG_+ +的timeStamp_;
文件storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
文件映像;
尝试{
图像= File.createTempFile(
映像文件名称,/ * preFIX * /
.JPG/ *后缀为* /
storageDir / *目录下的* /
);
返回image.getAbsolutePath();
}赶上(IOException异常五){
e.printStackTrace();
}
返回null;
} 私人诠释calculateInSampleSize(BitmapFactory.Options选项,诠释reqWidth,诠释reqHeight){
最终诠释身高= options.outHeight;
最终诠释宽度= options.outWidth;
INT inSampleSize = 1; 如果(高度> reqHeight ||宽度GT; reqWidth){
最终诠释heightRatio = Math.round((浮点)高度/(浮点)reqHeight);
最终诠释widthRatio = Math.round((浮点)宽/(浮点)reqWidth);
inSampleSize = heightRatio< widthRatio? heightRatio:widthRatio;
}
最终浮动totalPixels =宽*高;
最终浮动totalReqPixelsCap = reqWidth * reqHeight * 2; 而(totalPixels /(inSampleSize * inSampleSize)GT; totalReqPixelsCap){
inSampleSize ++;
}
返回inSampleSize;
}
}公共无效getBase64(){
COM pressBitmap COM pressBitmap =新的COM pressBitmap(picturePath);
//在ImageView的显示COM pressBitmap。 字节[]字节= NULL; 档案文件=新的文件(picturePath); ByteArrayOutputStream BOS = com的pressBitmap.getBitmap();
字节= bos.toByteArray();
的base64 = Base64.en codeToString(字节,Base64.DEFAULT); 返回的base64; //服务器发送的base64字符串
}
解决方案似乎缺少:
options.in preferQualityOverSpeed = TRUE;
I want to reduce the image file size below 100 KB while preserving the image quality like whatsapp and facebook did.
I tried almost all the code of android image compression available on stackoverflow but that doesn't work for me.
Right now i am following this blog to reduce the image size, and i am getting the image below 100 KB but image quality is poor.
Is there any way that i can reduce image size below 100 KB while preserving the quality??? (Original Image size can vary from 20 KB to 8 MB)
I tried JAI library in Java Project, and it work good.
Can i Use JAI library in android to reduce image size???
Thanks in Advance.
Source Code to compress an Image:
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.media.ExifInterface; import android.os.Environment; import android.util.Log; public class CompressBitmap { private String path; public CompressBitmap(String path){ this.path= path; } public ByteArrayOutputStream getBitmap(){ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); getscaledImage(path).compress(Bitmap.CompressFormat.JPEG, 100, outStream); return outStream; } public ByteArrayOutputStream getBitmap(int quality){ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); getscaledImage(path).compress(Bitmap.CompressFormat.JPEG, quality, outStream); return outStream; } public String getComressFile(){ FileOutputStream out = null; String filename = createImageFile(); try { out = new FileOutputStream(filename); getscaledImage(path).compress(Bitmap.CompressFormat.JPEG, 80, out); } catch (FileNotFoundException e) { e.printStackTrace(); } File file = new File(filename); Log.e("SIze of Image","Length"+file.length()); return filename; } private Bitmap getscaledImage(String filePath){ Bitmap scaledBitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(filePath,options); int actualHeight = options.outHeight; int actualWidth = options.outWidth; float maxHeight = 800.0f; float maxWidth = 600.0f; float imgRatio = actualWidth / actualHeight; float maxRatio = maxWidth / maxHeight; Log.v("Pictures", "Before scaling Width and height are " + actualWidth + "--" + actualHeight); if (actualHeight > maxHeight || actualWidth > maxWidth) { if (imgRatio < maxRatio) { imgRatio = maxHeight / actualHeight; actualWidth = (int) (imgRatio * actualWidth); actualHeight = (int) maxHeight; } else if (imgRatio > maxRatio) { imgRatio = maxWidth / actualWidth; actualHeight = (int) (imgRatio * actualHeight); actualWidth = (int) maxWidth; } else { actualHeight = (int) maxHeight; actualWidth = (int) maxWidth; } } options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); options.inJustDecodeBounds = false; options.inDither = false; options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[16*1024]; try{ bmp = BitmapFactory.decodeFile(filePath,options); } catch(OutOfMemoryError exception){ exception.printStackTrace(); } try{ scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); } catch(OutOfMemoryError exception){ exception.printStackTrace(); } float ratioX = actualWidth / (float) options.outWidth; float ratioY = actualHeight / (float)options.outHeight; float middleX = actualWidth / 2.0f; float middleY = actualHeight / 2.0f; Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); Canvas canvas = new Canvas(scaledBitmap); canvas.setMatrix(scaleMatrix); canvas.drawBitmap(bmp, middleX - bmp.getWidth()/2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG)); Log.v("Pictures", "After scaling Width and height are " + scaledBitmap.getWidth() + "--" + scaledBitmap.getHeight()); ExifInterface exif; try { exif = new ExifInterface(filePath); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); Log.d("EXIF", "Exif: " + orientation); Matrix matrix = new Matrix(); if (orientation == 6) { matrix.postRotate(90); Log.d("EXIF", "Exif: " + orientation); } else if (orientation == 3) { matrix.postRotate(180); Log.d("EXIF", "Exif: " + orientation); } else if (orientation == 8) { matrix.postRotate(270); Log.d("EXIF", "Exif: " + orientation); } scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); } catch (IOException e) { e.printStackTrace(); } return scaledBitmap; } private String createImageFile(){ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); File image; try { image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); return image.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } return null; } private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } final float totalPixels = width * height; final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { inSampleSize++; } return inSampleSize; } } public void getBase64() { CompressBitmap compressBitmap = new CompressBitmap(picturePath); //display compressBitmap in ImageView. byte[] bytes=null; File file= new File(picturePath); ByteArrayOutputStream bos = compressBitmap.getBitmap(); bytes = bos.toByteArray(); base64 = Base64.encodeToString(bytes, Base64.DEFAULT); return base64; // send base64 String on server }
解决方案Missing seems:
options.inPreferQualityOverSpeed = true;
这篇关于调整大小的图片,同时还美元的Android p $ pserving质量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!