1

哦,我的第一个问题~
这是我的问题。我正在制作一个应用程序来拍照并添加水印。
第一步,当应用程序启动时,我拍了一张(使用最大的分辨率,如2592*1952(5M))。拍照后,我按确定返回我的应用程序视图,应用程序崩溃。
但是,如果我在应用程序启动时以不太大的分辨率(如 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();
//              }   
            }

公共位图 mcreateBitmap(位图 src,字符串 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): 关闭 VM 01-05 11:25:25.801: W/dalvikvm(11147): threadid=1: 线程退出未捕获异常 (group=0x40028a00) 01-05 11:25:25.801 : E/AndroidRuntime(11147): 致命异常: main 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。

4

2 回答 2

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;
        }

    }

}
于 2013-01-03T13:17:44.870 回答
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)));

然后,一切正常。

于 2013-01-05T05:08:12.937 回答