哦,我的第一个问题〜
这是我的问题。我正在申请拍照并为其添加水印
第一步,当应用程序启动时,我拍摄(使用最大分辨率,如2592 * 1952(5M))。拍完照片后,按Ok键返回我的应用程序视图,应用程序崩溃。
但是,如果我在应用程序启动时拍摄的分辨率不是那么大(如3M,2M,1M),它可以正常工作。然后,第二个镜头,分辨率为5M,无论哪种方式都有趣。
我很困惑。任何人都可以帮助我吗?
以下是有关解码图像文件的一些代码。
public void onClick(View v){
Bitmap bitmap1 =mcreateBitmap(bitmaptmp, "watermark");
// bitmaptmp=null;
/* Associate the Bitmap to the ImageView */
if (bitmap1 != null) {
mImageView.setImageBitmap(bitmap1);
}
mImageView.setVisibility(View.VISIBLE);
// try {
// String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
// String imageFileName = JPEG_FILE_PREFIX + timeStamp;
// saveMyBitmap(imageFileName,bitmap1);
// bitmap1=null;
// } catch (IOException e) {
// e.printStackTrace();
// }
}
public Bitmap mcreateBitmap(Bitmap src,String str){
Time t = new Time();
t.setToNow();
int w = src.getWidth();
int h = src.getHeight();
String mstrTitle = "11:"+t.hour + ":" + t.minute + ":" + t.second;
String xx="34:"+x;
String yy="44:"+y;
Bitmap bmpTemp = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(bmpTemp);
Paint photoPaint = new Paint();
photoPaint.setDither(true);
photoPaint.setFilterBitmap(true);
Rect s = new Rect(0, 0, src.getWidth(), src.getHeight());
Rect d = new Rect(0, 0, w, h);
canvas.drawBitmap(src, s, d, photoPaint);
String familyName = "new";
Typeface font = Typeface.create(familyName, Typeface.BOLD);
photoPaint.setColor(Color.BLUE);
photoPaint.setTypeface(font);
photoPaint.setTextSize(18);
canvas.drawText(mstrTitle,40, 20, photoPaint);
canvas.drawText(xx,40, 40, photoPaint);
canvas.drawText(yy,40, 60, photoPaint);
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
return bmpTemp;
}
这是logCat:
01-05 11:25:25.791:E / dalvikvm-heap(11147):20238336字节的外部分配对于此过程来说太大了。
01-05 11:25:25.791:E / dalvikvm(11147):内存不足:堆大小= 2923KB,分配= 2460KB,位图大小= 1235KB,限制= 13756KB
01-05 11:25:25.791:E / dalvikvm(11147):修剪信息:足迹= 2883KB,允许的足迹= 3267KB,修剪= 344KB
01-05 11:25:25.791:E / GraphicsJNI(11147):VM不会让我们分配20238336字节
01-05 11:25:25.801:D / AndroidRuntime(11147):关闭虚拟机
01-05 11:25:25.801:W / dalvikvm(11147):threadid = 1:线程退出未捕获异常(组= 0x40028a00)
01-05 11:25:25.801:E / AndroidRuntime(11147):致命异常:主要
01-05 11:25:25.801:E / AndroidRuntime(11147):java.lang.OutOfMemoryError:位图大小超过VM预算
01-05 11:25:25.801:E / AndroidRuntime(11147):在android.graphics.Bitmap.nativeCreate(Native Method)
01-05 11:25:25.801:E / AndroidRuntime(11147):在android.graphics.Bitmap.createBitmap(Bitmap.java:574)
01-05 11:25:25.801:E / AndroidRuntime(11147):at com.kevin.photowatermark.PhotowatermarkActivity.mcreateBitmap(PhotowatermarkActivity.java:403)
答案 0 :(得分:1)
对于解码文件,您应该使用以下方法。您的问题是由于内存问题而发生的。因此,使用以下方法解码从相机设备捕获的图像(位图)。
package com.example.stackoverflow;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigInteger;
import java.security.SecureRandom;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
public class MyCameraActivity extends Activity {
private static final int CAMERA_REQUEST = 1888;
static String str_Camera_Photo_ImagePath = "";
private static File f;
private static int Take_Photo = 2;
private static String str_randomnumber = "";
static String str_Camera_Photo_ImageName = "";
public static String str_SaveFolderName;
private static File wallpaperDirectory;
Bitmap bitmap;
int storeposition = 0;
public static GridView gridview;
public static ImageView imageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ccccc);
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
photoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
str_SaveFolderName = Environment
.getExternalStorageDirectory()
.getAbsolutePath()
+ "/rajeshsample";
str_randomnumber = String.valueOf(nextSessionId());
wallpaperDirectory = new File(str_SaveFolderName);
if (!wallpaperDirectory.exists())
wallpaperDirectory.mkdirs();
str_Camera_Photo_ImageName = str_randomnumber
+ ".jpg";
str_Camera_Photo_ImagePath = str_SaveFolderName
+ "/" + str_randomnumber + ".jpg";
System.err.println(" str_Camera_Photo_ImagePath "
+ str_Camera_Photo_ImagePath);
f = new File(str_Camera_Photo_ImagePath);
startActivityForResult(new Intent(
MediaStore.ACTION_IMAGE_CAPTURE).putExtra(
MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)),
Take_Photo);
System.err.println("f " + f);
}
});
}
// used to create randon numbers
public String nextSessionId() {
SecureRandom random = new SecureRandom();
return new BigInteger(130, random).toString(32);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Take_Photo) {
String filePath = null;
filePath = str_Camera_Photo_ImagePath;
if (filePath != null) {
Bitmap faceView = ( new_decode(new File(
filePath))); // ========================> good
// lines
imageView.setImageBitmap(faceView);
} else {
bitmap = null;
}
}
}
public static Bitmap new_decode(File f) {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inDither = false; // Disable Dithering mode
o.inPurgeable = true; // Tell to gc that whether it needs free memory,
// the Bitmap can be cleared
o.inInputShareable = true; // Which kind of reference will be used to
// recover the Bitmap data after being
// clear, when it will be used in the future
try {
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 300;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 1.5 < REQUIRED_SIZE && height_tmp / 1.5 < REQUIRED_SIZE)
break;
width_tmp /= 1.5;
height_tmp /= 1.5;
scale *= 1.5;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
// o2.inSampleSize=scale;
o.inDither = false; // Disable Dithering mode
o.inPurgeable = true; // Tell to gc that whether it needs free memory,
// the Bitmap can be cleared
o.inInputShareable = true; // Which kind of reference will be used to
// recover the Bitmap data after being
// clear, when it will be used in the future
// return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
try {
// return BitmapFactory.decodeStream(new FileInputStream(f), null,
// null);
Bitmap bitmap= BitmapFactory.decodeStream(new FileInputStream(f), null, null);
System.out.println(" IW " + width_tmp);
System.out.println("IHH " + height_tmp);
int iW = width_tmp;
int iH = height_tmp;
return Bitmap.createScaledBitmap(bitmap, iW, iH, true);
} catch (OutOfMemoryError e) {
// TODO: handle exception
e.printStackTrace();
// clearCache();
// System.out.println("bitmap creating success");
System.gc();
return null;
// System.runFinalization();
// Runtime.getRuntime().gc();
// System.gc();
// decodeFile(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
答案 1 :(得分:1)
旧代码:
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
新代码:
if (photoH > IMAGE_MAX_SIZE || photoW> IMAGE_MAX_SIZE) {
scaleFactor = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(photoH, photoW)) / Math.log(0.5)));
然后,它可以正常工作。