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;
}
}
}
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.It means that you do not have enough memory for whatever it is you are trying to do.
Yes.
Copy and paste usually works. :-)
To tell the camera what size picture to take, use
setPictureSize()
onCamera.Parameters
. However, you have to choose a size it supports, and not all devices will support arbitrary sizes. CallinggetSupportedPictureSizes()
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.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.Try this capturing image from Camera.
This will return you large size image , now for scaling it down u can use something like this
Now u can add on click on this .