天,我已经花在了这个上面。也许是几周。从字面上看。 :(
所以我在SD卡上有一张图像,很可能是内置摄像头出来的。我想拍摄该图像并将其下采样到任意大小(但总是更小,从不更大)。我的代码使用标准的Android Bitmap方法来解码,调整大小,重新压缩和保存图像。只要最终图像小于3MP左右,一切正常。如果图像较大,或者我尝试同时执行其中的几个,则应用程序会因OutOfMemoryError崩溃。我知道为什么会这样,我知道这是出于一个完全正当的理由,我只是希望它不再发生。
看,我不是想在这里发射火箭。我想要做的就是调整相机图像的大小并将其转储到OutputStream甚至是临时文件。当然有人在那里一定做过这样的事情。我不需要你为我编写代码,我也不需要手持。但在我的各种编程堕胎和痴迷谷歌的日子之间,我甚至都不知道要进入哪个方向。粗略地说,有没有人知道如何解码JPEG,对其进行缩减采样,以JPEG格式重新压缩,然后将其发送出去在没有分配大量内存的OutputStream上?
答案 0 :(得分:3)
好的,我知道它有点迟了但是,我遇到了这个问题,我找到了解决办法。它实际上很容易,我相信它支持api 10(我在10之前不知道)。我用手机试过了。它是一个拥有8mp相机的三星Galaxy s2,代码完美地调整了相机图像到168x168以及我在网络上找到的图像。我也使用文件管理器检查了图像。我从未尝试过将图像调整为更大的重建。
private Bitmap resize(Bitmap bp, int witdh, int height){
return Bitmap.createScaledBitmap(bp, width, height, false);
}
你可以像这样保存它
private void saveBitmap(Bitmap bp) throws FileNotFoundException{
String state = Environment.getExternalStorageState();
File folder;
//if there is memory card available code choose that
if (Environment.MEDIA_MOUNTED.equals(state)) {
folder=Environment.getExternalStorageDirectory();
}else{
folder=Environment.getDataDirectory();
}
folder=new File(folder, "/aaaa");
if(!folder.exists()){
folder.mkdir();
}
File file=new File(folder, (int)(Math.random()*10000)+".jpg");
FileOutputStream os=new FileOutputStream(file);
bp.compress(Bitmap.CompressFormat.JPEG, 90, os);
}
感谢这个link
答案 1 :(得分:0)
以下代码来自我之前的项目。关键点是“options.inSampleSize”。
public static Bitmap makeBitmap(String fn, int minSideLength, int maxNumOfPixels) {
BitmapFactory.Options options;
try {
options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fn, options);
if (options.mCancel || options.outWidth == -1
|| options.outHeight == -1) {
return null;
}
options.inSampleSize = computeSampleSize(
options, minSideLength, maxNumOfPixels);
options.inJustDecodeBounds = false;
//Log.e(LOG_TAG, "sample size=" + options.inSampleSize);
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeFile(fn, options);
} catch (OutOfMemoryError ex) {
Log.e(LOG_TAG, "Got oom exception ", ex);
return null;
}
}
private static int computeInitialSampleSize(BitmapFactory.Options options,
int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
(int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :
(int) Math.min(Math.floor(w / minSideLength),
Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == UNCONSTRAINED) &&
(minSideLength == UNCONSTRAINED)) {
return 1;
} else if (minSideLength == UNCONSTRAINED) {
return lowerBound;
} else {
return upperBound;
}
}