Android的减小尺寸相机图片 [英] Android Reduce Size Of Camera Picture

查看:143
本文介绍了Android的减小尺寸相机图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新,也许改变位图的大小在新的活动可能会解决问题

 字符串myRef = this.getIntent()getStringExtra(文件路径)。
    文件imgFile =新的文件(myRef);

    Log.e(BeatEmUp,myRef);
    如果(imgFile.exists()){

        位图MYBITMAP = BitmapFactory.de codeFILE(imgFile.getAbsolutePath());
        ImageView的MYIMAGE =(ImageView的)findViewById(R.id.imagepunch);
        myImage.setImageBitmap(MYBITMAP);

    }
 

这样的事情可能?

位图缩放= Bitmap.createScaledBitmap(位,200,200,真);

或也许这就是下面的最好办法

到目前为止,我有我的应用程序,它是拍摄照片,然后使用意图结束,显示携带的图片在一个新的活动。有一次,我已经做到了这一点,我有一些code这在与的onClick 顶部显示的图像。问题是,当图像被就把它正在采取的最大规模​​我觉得这样我的应用程序的力量结束。

在我的logcat我正在 java.lang.OutOfMemoryError:位图大小超过VM预算(堆大小= 7431KB,分配= 2956KB,位图大小= 19764KB)我认为意味着图像太大。

我已通过把较小的图像中的code,代替被拿着摄像机图像进行测试并且工作这也导致我回到它是摄像机图像的大小的问题。

所以我想实现<一个href="https://github.com/commonsguy/cw-advandroid/blob/master/Camera/Picture/src/com/commonsware/android/picture/PictureDemo.java">This从CommonsWare 但至今没有运气。翻翻code,我认为它搜索的最小resouloution /大小,然后需要使用这些设置是我的相机就在想,如果是的话我怎么可以实现了我的code?

 公共类AndroidCamera扩展活动实现SurfaceHolder.Callback {

摄像头摄像头;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
布尔previewing = FALSE;
LayoutInflater controlInflater = NULL;

最终诠释RESULT_SAVEIMAGE = 0;

/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);



    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    。getWindow()和setFormat(PixelFormat.UNKNOWN);
    surfaceView =(SurfaceView)findViewById(R.id.camera preVIEW);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(本);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    controlInflater = LayoutInflater.from(getBaseContext());
    查看viewControl = controlInflater.inflate(R.layout.control,NULL);
    的LayoutParams layoutParamsControl
        =新的LayoutParams(LayoutParams.FILL_PARENT,
        LayoutParams.FILL_PARENT);
    this.addContentView(viewControl,layoutParamsControl);

    按钮buttonTakePicture =(按钮)findViewById(R.id.takepicture);
    buttonTakePicture.setOnClickListener(新Button.OnClickListener(){

        公共无效的onClick(查看为arg0){
            // TODO自动生成方法存根
            camera.takePicture(myShutterCallback,
                    myPictureCallback_RAW,myPictureCallback_JPG);



        }});

}

ShutterCallback myShutterCallback =新ShutterCallback(){

    公共无效onShutter(){
        // TODO自动生成方法存根

    }};

PictureCallback myPictureCallback_RAW =新PictureCallback(){

    公共无效onPictureTaken(byte []的为arg0,摄像机ARG1){
        // TODO自动生成方法存根

    }};

PictureCallback myPictureCallback_JPG =新PictureCallback(){

    公共无效onPictureTaken(byte []的为arg0,摄像机ARG1){
        // TODO自动生成方法存根
        / *位图bitmapPicture
            = BitmapFactory.de codeByteArray(为arg0,0,arg0.length); * /
        INT imageNum = 0;
        意图imageIntent =新的意图(android.provider.MediaStore.ACTION_IM​​AGE_CAPTURE);
        文件imagesFolder =新的文件(Environment.getExternalStorageDirectory(),冲);
        imagesFolder.mkdirs(); //&LT; ----
        字符串文件名=image_+将String.valueOf(imageNum)+.JPG;
        文件输出=新的文件(imagesFolder,文件名);
        而(output.exists()){
            imageNum ++;
            文件名=image_+将String.valueOf(imageNum)+.JPG;
            输出=新的文件(imagesFolder,文件名);
        }

        乌里uriSavedImage = Uri.fromFile(输出);
        imageIntent.putExtra(MediaStore.EXTRA_OUTPUT,uriSavedImage);


        的OutputStream imageFileOS;
        尝试 {
            imageFileOS = getContentResolver()openOutputStream(uriSavedImage)。
            imageFileOS.write(为arg0);
            imageFileOS.flush();
            imageFileOS.close();

            Toast.makeText(AndroidCamera.this,
                    图像存储,
                    Toast.LENGTH_LONG).show();

        }赶上(FileNotFoundException异常E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }赶上(IOException异常E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }

        意向意图=新的意图(getBaseContext(),Punch.class);
        intent.putExtra(文件路径,Uri.parse(output.getAbsolutePath())的toString());
        //只是用零请求code
        INT请求= 0;
        startActivityForResult(意向,要求);
    }};

公共无效surfaceChanged(SurfaceHolder持有人,INT格式,诠释的宽度,
        INT高度){
    // TODO自动生成方法存根
    如果(previewing){
        camera.stop preVIEW();
        previewing = FALSE;
    }

    如果(相机!= NULL){
        尝试 {
            camera.set previewDisplay(surfaceHolder);
            camera.start preVIEW();
            previewing = TRUE;
        }赶上(IOException异常E){
            // TODO自动生成的catch块
            camera.release();
            e.printStackTrace();
        }
    }
}





公共无效surfaceCreated(SurfaceHolder持有者){
    // TODO自动生成方法存根

    相机= Camera.open();
    尝试 {
           Camera.Parameters参数= camera.getParameters();

           如果(this.getResources()。getConfiguration()。方向!= Configuration.ORIENTATION_LANDSCAPE){
              //这是一个无证虽然广为人知的功能
              parameters.set(方向,肖像);
              //为Android 2.2及以上
              camera.setDisplayOrientation(90);
              //取消注释为Android 2.0及以上
              parameters.setRotation(90);
           } 其他 {
              //这是一个无证虽然广为人知的功能
              parameters.set(方向,山水);
              //为Android 2.2及以上
              camera.setDisplayOrientation(0);
              //取消注释为Android 2.0及以上
              parameters.setRotation(0);
           }


          camera.setParameters(参数);
          camera.set previewDisplay(保持器);
      }赶上(IOException异常除外){
         camera.release();


       }
        camera.start preVIEW();

    }


公共无效surfaceDestroyed(SurfaceHolder持有者){
    // TODO自动生成方法存根
    如果(previewing和放大器;&安培;!摄像头= NULL){
        如果(相机!= NULL){
            camera.stop preVIEW();
            camera.release();
            摄像头= NULL;
        }
        previewing = FALSE;
    }
}


}
 

解决方案
  

到目前为止,我有我的应用程序,它是拍摄照片,然后使用一个Intent结束,显示携带的图片在一个新的活动。

在大多数情况下,使用意图其他活动之间传递的数据是一个很好的解决方案。大位图,不过,会出现问题,由于内存消耗方式。这是一种情况我会的精心的使用静态数据成员。

  

在我的logcat我收到java.lang.OutOfMemoryError:位图大小超过VM预算(堆大小= 7431KB,分配= 2956KB,位图大小= 19764KB),我认为这意味着图像太大

这意味着你没有足够的内存不管它是你正在尝试做的。

  

翻翻code,我认为它搜索的最小resouloution /大小,然后使用这些设置,拍摄摄像机我我就在想,

是的。

  

如果让我如何可以实现了我的code?

复制和粘贴通常工作。 : - )

要告诉相机采取什么大小的图片,可以使用 setPictureSize() Camera.Parameters 。但是,你要选择它支持的大小,而不是所有的设备都支持任意大小。呼叫 getSupportedPictureSizes()会告诉你,这是支持的尺寸。它是由你来确定要使用的那些尺寸。在我联系从您的其他问题的例子,我遍历这些尺寸和发现最小的一个以面积计算。

话虽这么说,如果的只有的问题,图像大小是从活动传递到活动中,我会先去静态数据成员的路线。只要确保指出,静态数据成员,当你不再需要的图像。

  

这样的事情可能?

此外,这取决于你的目标是什么。你似乎挥舞着四处寻找解决方案,当你只阐述一个问题(而且,即使在那里,你还没有告诉我们的其中的你所得到的内存不足错误)。

如果你的目标是采取全分辨率的图片,将其保存在一个文件中,然后保留在内存中的缩略图, createScaledBitmap()是一个很好的解决方案。

如果你的目标是把一个缩略图上下的画面摆在首位(即你不需要或不想要一个全分辨率图像),使用 setPictureSize()

如果你的目标是在整个使用全分辨率的图片,仔细地使用静态数据成员,以消除位图中的任何不必要的复制键,看看是否是足够的。它可能不是,这取决于你正在努力做的像什么。

UPDATE maybe changing the Bitmap size in the new Activity may fix the problem

String myRef = this.getIntent().getStringExtra("filepath");
    File imgFile = new  File(myRef);

    Log.e("BeatEmUp", myRef);
    if(imgFile.exists()){

        Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
        ImageView myImage = (ImageView) findViewById(R.id.imagepunch);
        myImage.setImageBitmap(myBitmap);

    }

Something like this maybe?

Bitmap scaled = Bitmap.createScaledBitmap(bit, 200, 200, true);

Or Maybe this is the best way below

So far I have my app which is taking a picture and then using an Intent to carry the picture over and display in a new Activity. Once I have done this I have some code which displays images over the top with the onClick. The problem is when the image is took it is being taken at a maximum size I think so my app is force closing.

In my logcat I am getting java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) which I think means that the image is too large.

I have tested by putting a smaller image in the code instead of the camera image that was took and that works which also leads me back to the problem that it is the size of the camera picture.

So I am trying to implement This From CommonsWare but with no luck so far. Looking through the code I think it searches for the smallest resouloution/size and then takes the camera using those settings am I right in thinking that and if so how can I implement that into my code?

public class AndroidCamera extends Activity implements SurfaceHolder.Callback{

Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;

final int RESULT_SAVEIMAGE = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    getWindow().setFormat(PixelFormat.UNKNOWN);
    surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    controlInflater = LayoutInflater.from(getBaseContext());
    View viewControl = controlInflater.inflate(R.layout.control, null);
    LayoutParams layoutParamsControl 
        = new LayoutParams(LayoutParams.FILL_PARENT, 
        LayoutParams.FILL_PARENT);
    this.addContentView(viewControl, layoutParamsControl);

    Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
    buttonTakePicture.setOnClickListener(new Button.OnClickListener(){

        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            camera.takePicture(myShutterCallback, 
                    myPictureCallback_RAW, myPictureCallback_JPG);



        }});

}

ShutterCallback myShutterCallback = new ShutterCallback(){

    public void onShutter() {
        // TODO Auto-generated method stub

    }};

PictureCallback myPictureCallback_RAW = new PictureCallback(){

    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub

    }};

PictureCallback myPictureCallback_JPG = new PictureCallback(){

    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        /*Bitmap bitmapPicture 
            = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);  */
        int imageNum = 0;
        Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
        imagesFolder.mkdirs(); // <----
        String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
        File output = new File(imagesFolder, fileName);
        while (output.exists()){
            imageNum++;
            fileName = "image_" + String.valueOf(imageNum) + ".jpg";
            output = new File(imagesFolder, fileName);
        }

        Uri uriSavedImage = Uri.fromFile(output);
        imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);


        OutputStream imageFileOS;
        try {
            imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
            imageFileOS.write(arg0);
            imageFileOS.flush();
            imageFileOS.close();

            Toast.makeText(AndroidCamera.this, 
                    "Image saved", 
                    Toast.LENGTH_LONG).show();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Intent intent = new Intent(getBaseContext(), Punch.class);
        intent.putExtra("filepath",Uri.parse(output.getAbsolutePath()).toString());
        //just using a request code of zero
        int request=0;
        startActivityForResult(intent,request); 
    }};

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
    if(previewing){
        camera.stopPreview();
        previewing = false;
    }

    if (camera != null){
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            previewing = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            camera.release();
            e.printStackTrace();
        }
    }
}





public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub

    camera = Camera.open();
    try {
           Camera.Parameters parameters = camera.getParameters();

           if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
              // This is an undocumented although widely known feature
              parameters.set("orientation", "portrait");
              // For Android 2.2 and above
              camera.setDisplayOrientation(90);
              // Uncomment for Android 2.0 and above
              parameters.setRotation(90);
           } else {
              // This is an undocumented although widely known feature
              parameters.set("orientation", "landscape");
              // For Android 2.2 and above
              camera.setDisplayOrientation(0);
              // Uncomment for Android 2.0 and above
              parameters.setRotation(0);
           }


          camera.setParameters(parameters);
          camera.setPreviewDisplay(holder);
      } catch (IOException exception) {
         camera.release();


       }
        camera.startPreview();

    }


public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    if(previewing && camera != null) {
        if(camera!=null) {
            camera.stopPreview();
            camera.release();  
            camera = null;
        }
        previewing = false;
    }
}


}

解决方案

So far I have my app which is taking a picture and then using an Intent to carry the picture over and display in a new Activity.

In most cases, passing data between activities using Intent extras is a fine solution. Large bitmaps, though, cause problems that way due to memory consumption. This is one case where I would carefully use a static data member.

In my logcat I am getting java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) which I think means that the image is too large.

It means that you do not have enough memory for whatever it is you are trying to do.

Looking through the code I think it searches for the smallest resouloution/size and then takes the camera using those settings am I right in thinking that

Yes.

if so how can I implement that into my code?

Copy and paste usually works. :-)

To tell the camera what size picture to take, use setPictureSize() on Camera.Parameters. However, you have to choose a size it supports, and not all devices will support arbitrary sizes. Calling getSupportedPictureSizes() will tell you which sizes are supported. It is up to you to determine which of those sizes to use. In the example I linked to from your other question, I iterate over those sizes and find the smallest one in terms of area.

That being said, if the only issue with image size is passing it from activity to activity, I would go the static data member route first. Just be sure to null out that static data member when you no longer need the image.

Something like this maybe?

Again, that depends on what your objective is. You seem to be flailing around looking for solutions, when you have only articulated one problem (and, even there, you have not told us where you are getting the out of memory error).

If your goal is to take a full-resolution picture, save it in a file, and then hold in memory a thumbnail, createScaledBitmap() is a fine solution.

If your goal is to take a thumbnail-ish picture in the first place (i.e., you do not need or want a full-resolution image), use setPictureSize().

If your goal is to use a full-resolution picture throughout, carefully use a static data member to eliminate any unnecessary copies of the Bitmap and see if that is sufficient. It might not be, depending on what you are trying to do with the image.

这篇关于Android的减小尺寸相机图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆