Android уменьшает размер изображения камеры

UPDATE, возможно, изменение размера Bitmap в новой Activity может решить проблему

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

Что-то вроде этого, может быть?

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

Или, может быть, это лучший способ ниже

Пока у меня есть приложение, которое делает снимок, а затем использует Intent для переноса изображения и отображения в новом Activity . Как только я это сделал, у меня есть код, который отображает изображения сверху с помощью onClick . Проблема в том, когда изображение взято, оно берется с максимальным размером, я думаю, поэтому мое приложение закрывает силу.

В моем logcat я получаю java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) что, я думаю, означает, что изображение слишком велико.

Я тестировал, помещая меньшее изображение в код вместо изображения камеры, которое было принято, и что работает, что также приводит меня к проблеме, что это размер изображения камеры.

Поэтому я пытаюсь реализовать это с CommonsWare, но пока не повезло. Просматривая код, я думаю, что он ищет самый маленький resuloution / size, а затем снимает камеру с помощью этих настроек. Я прав, думая об этом, и если да, то как я могу реализовать это в своем коде?

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

Пока у меня есть приложение, которое делает снимок, а затем использует намерение для переноса изображения и отображения в новом действии.

В большинстве случаев передача данных между действиями с использованием опций Intent является прекрасным решением. Однако большие растровые изображения вызывают проблемы из-за потребления памяти. Это один случай, когда я бы осторожно использовал статический элемент данных.

В моем logcat я получаю java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет VM (размер кучи = 7431 КБ, выделенный = 2956 КБ, размер растрового изображения = 19764 КБ), что, я думаю, означает, что изображение слишком велико.

Это означает, что у вас недостаточно памяти для того, что вы пытаетесь сделать.

Просматривая код, я думаю, что он ищет самый маленький resuloution / size, а затем снимает камеру с помощью этих настроек. Я правильно понимаю, что

Да.

Если да, то как я могу реализовать это в своем коде?

Обычно работает копирование и вставка. 🙂

Чтобы сообщить какому-либо размеру изображения, используйте setPictureSize() на Camera.Parameters . Однако вам нужно выбрать размер, который он поддерживает, и не все устройства будут поддерживать произвольные размеры. Вызов getSupportedPictureSizes() подскажет вам, какие размеры поддерживаются. Вам решать, какой из этих размеров использовать. В примере, который я связал с вашим другим вопросом, я перебираю эти размеры и нахожу наименьший по площади.

При этом, если единственная проблема с размером изображения передаёт его от активности к активности, я бы сначала отправил статический член данных. Просто не забудьте удалить этот статический член данных, когда вам больше не нужен образ.

Что-то вроде этого, может быть?

Опять же, это зависит от вашей цели. Кажется, вы сталкиваетесь с поиском решений, когда вы только сформулировали одну проблему (и даже там вы не сказали нам, где вы получаете ошибку из памяти).

Если ваша цель – сделать изображение с полным разрешением, сохранить его в файле, а затем сохранить в памяти миниатюру, createScaledBitmap() – прекрасное решение.

Если ваша цель состоит в том, чтобы сначала сделать снимок с миниатюрным изображением (т. setPictureSize() Вам не нужен или требуется изображение с полным разрешением), используйте setPictureSize() .

Если ваша цель – использовать изображение с полным разрешением, тщательно используйте элемент статических данных, чтобы устранить ненужные копии Bitmap и посмотреть, достаточно ли этого. Возможно, это не так, в зависимости от того, что вы пытаетесь сделать с изображением.

Попробуйте захватить изображение с камеры.

 Intent cameraActivity=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraActivity.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(left)); startActivityForResult(cameraActivity,CAMERA_PIC_REQUEST_LEFTIMAGE); 

Это вернет вам изображение большого размера, теперь для его масштабирования вы можете использовать что-то вроде этого

  BitmapFactory.Options options=new BitmapFactory.Options(); options.inSampleSize = 6; FileInputStream fileInputStream; try { fileInputStream=new FileInputStream(left); leftPhoto=BitmapFactory.decodeStream(fileInputStream,null,options); leftImage.setImageBitmap(leftPhoto); fileInputStream.close(); } catch (FileNotFoundException e) { Toast.makeText(getCurrentContext(), e.getMessage(),Toast.LENGTH_LONG).show(); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getCurrentContext(), e.getMessage(),Toast.LENGTH_LONG).show(); } 

Теперь вы можете добавить на это щелчок.