Resaving combined Bitmaps - android

I am trying to open a bitmap that has already been stored in SdCard as follows:
String imageFilePath= "/sdcard/SoftCopy/"+mybitmap.png;
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
Bitmap loadedWork= BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
I have a second Bitmap named currentWork. This bitmap is actually the current drawing that has been done. I have combined two bitmaps as follows:
Canvas c = new Canvas(loadedWork);
c.drawBitmap(currentWork, 0, 0, null); //so that currentWork get drawn on loadedWork
Now i am saving the combined bitmap (now in loadedWork) to file as follows:
try {
final FileOutputStream out = new FileOutputStream(new File("/sdcard/SoftCopy" + "/mybitmap.png"));
loadedWork.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
return true;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
THE problem is that the combined bitmap(loadedWork) gets saved as png file for 1st time and i am able to load it, however WHEN I AGAIN TRY TO SAVE AFTER MAKING SOME MODIFICATIOns, then the application crashes. Can someone tell me how can I be able to resave the combined bitmap.

Related

How to insert Exif information to a new image?

I just create an image that comes from the camera on an Android application:
YuvImage yuv = new YuvImage(
byteArrayDataFromCamera,
camera.getParameters().getPreviewFormat(),
imageWidth,
imageHeight, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, imageWidth, imageHeight, 100, out);
byte[] bytes = out.toByteArray();
Bitmap image = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
And I want to add Exif information to it. Since now I've tried this:
// Save image on SD
storeImage(image, "Image_0.jpg");
String filePath = Environment.getExternalStorageDirectory() + "/MyFolder/Image_0.jpg";
try {
ExifInterface exif = new ExifInterface(filePath);
exif.setAttribute("UserComment", "my custom comment");
exif.saveAttributes();
}
catch (IOException e) {
e.printStackTrace();
}
The storeImage method:
private boolean storeImage(Bitmap imageData, String filename) {
//get path to external storage (SD card)
String iconsStoragePath = Environment.getExternalStorageDirectory() + "/MyFolder/";
File sdIconStorageDir = new File(iconsStoragePath);
//create storage directories, if they don't exist
sdIconStorageDir.mkdirs();
try {
String filePath = sdIconStorageDir.toString() + filename;
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
//choose another format if PNG doesn't suit you
imageData.compress(CompressFormat.PNG, 100, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
Log.w("TAG", "Error saving image file: " + e.getMessage());
return false;
} catch (IOException e) {
Log.w("TAG", "Error saving image file: " + e.getMessage());
return false;
}
return true;
}
As my image is recently created, it doesn't have any ExifInterface information. I want to know how to add new ExifInterface to my recently created image. How can achieve this?
I know that you can add rotation in image information but to add comment it's more complicated. The Exif class doesn't work correctly... Because you can read Exif information from stream but you can write this information. When I search information to add image info the users have the same problem as you, and I know that existing libraries to add information in image information...
When I find the post I give you the URL!!
I can find the post, read this!!
Tell me if I helped you and good programming!

byte[] to png file in Android

Hi I am working on application which gets .png files in byte stream from server. When I got it I try to make from it bmp and later convert it to .png file, but the following method ( Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length); ) returns me null.
Here is my code:
byte[] result
Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length);
try {
File filename = new File(imageUri.getPath()+name);
File parentFile = new File(imageUri.getPath());
parentFile.mkdirs();
FileOutputStream out = new FileOutputStream(filename);
img.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
Log.e("imageDownloaded", e.toString());
} catch (Exception e) {
Log.e("imageDownloaded", e.toString());
}
but the img Bitmap is always, null. I uploaded the image as multi part data and it was png file parsed to byte array, but now when i want to retrieve it i get this ugly null. Thanks for any help.

Android: Efficient way to grab image from camera and send it to server

I need my App to take a photo using the camera, show it in my Activities ImageView, and then sent it to a server using an HttpClient. So far, so good. Unfortunately, I stumbled upon the well described MemoryOutOfBoundsException. So I want to compress my image using JPG or PNG.
Now - after some excessive googling - do I get this right:
a) The camera will always output an uncompressed Bitmap, which is directly written to the file system. I.e. like this:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.imageTempFile = new File(android.os.Environment.getExternalStorageDirectory(), "myTempFileName"); // write the camera output to a tmpFile
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.imageTempFile)); // link the tmpFile to a member for convenience later on
startActivityForResult(cameraIntent, CAMERA_REQUEST);
So there is no way to resize / compress it right away?
b) If I want to display an image in a ImageView, I need to pass a Bitmap to it using ImageView.setImageBitmap(Bitmap bm). So showing the result is extremely memory consuming...!?
c) If I want to alter the Bitmap (resize / compress), I need to read it from this file into memory using a BitmapFactory
d) Now I can resize the Bitmap using Bitmap.createScaledBitmap()
e) But if I want to compress the image, I need to write it back to the file system using an OutputStream via Bitmap.compress()...
f) So for the task of taking an image, resizing it, showing it, and then sending it to a server, I need to actually write it to a file, then read it, then write it to a file again, then read it - and then send it? WTF? I there no easier way?
PS: Here's my code for b) to e):
// c) read the Bitmap from file
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(this.imageTempFile.getAbsolutePath(), bitmapOptions);
// d) do some resizing
bitmap = Bitmap.createScaledBitmap(bitmap, (int) mywidth, (int) myheight, true);
// e) compress
OutputStream out = new ByteArrayOutputStream(50);
this.imageTempFile.delete();
File file = new File(this.imageTempFile.getAbsolutePath());
try {
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// NOW we could read it again from the file to send it afterwards...
Bitmap newBitmap = BitmapFactory.decodeFile(this.imageTempFile.getAbsolutePath(), bitmapOptions);

Black portion in place of transparent portion while saving the bitmap

I am frustrated searching almost every google page for this problem.
I need to save my bitmap to file.
I have used this method several times with no problem at all. But now I am having a problem.
The Bitmap I am saving is a round image with transparency and having .png format which I have placed in res folder. But I am getting black portion in place of transparent portion.
This is the code I am using for saving the bitmap.
void saveImage(Bitmap bmp) {
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, bytes);
finalImg = new File(Environment.getExternalStorageDirectory(),
"emoticon_temp" + ".png");
finalImg.createNewFile();
FileOutputStream fo = new FileOutputStream(finalImg);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I am saving this bitmap as file because I need to share this image and for sharing the image I need the Stream Uri.
If you got any other Idea for sharing a bitmap, please let me know.

How to take a screenshot of Android's Surface View?

I want to programatically take screen shot of my game, just as you'd get in Eclipse DDMS.
Screenshot taken through the solution proposed here: How to programmatically take a screenshot in Android? and in most other SO questions only have View elements visible, but not the SurfaceView.
SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get root view
View view = activity.getWindow().getDecorView().getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d("ScreenShot", "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any help in this regard would be highly appreciated. Thanks.
I hope this also useful for you. here little difference for the above answer is
for I used glsurfaceview to take the screen shots hen i click the button.
this image is stored in sdcard for mentioned folder :
sdcard/emulated/0/printerscreenshots/image/...images
My Program :
View view_storelayout ;
view_storelayout = findViewById(R.id.gl_surface_view);
button onclick() {
view_storelayout.setDrawingCacheEnabled(true);
view_storelayout.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(view_storelayout.getDrawingCache());
view_storelayout.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 90, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
final Calendar c=Calendar.getInstance();
long mytimestamp=c.getTimeInMillis();
String timeStamp=String.valueOf(mytimestamp);
String myfile="hari"+timeStamp+".jpeg";
dir_image=new File(Environment.getExternalStorageDirectory()+
File.separator+"printerscreenshots"+File.separator+"image");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "myPath:"
+dir_image.toString(), Toast.LENGTH_SHORT).show();
Log.v("hari", "screenshots:"+dir_image.toString());
}
Note :
But, here i am faced one problem. In this surfaceview , i drawn line and circle
at runtime. after drawn some objects, when i take screenshots , its stored only for
black image like surfaceview is stored as an image.
And also i want to store that surfaceview image as an .dxf format(autocad format).
i tried to stored image file as an .dxf file format.its saved successfully in
autocad format. but, it cant open in autocad software to edit my .dxf file.
The code from the Usman Kurd answer will not work is most cases.
Unless you're rendering H.264 video frames in software with Canvas onto a View, the drawing-cache approach won't work (see e.g. this answer).
You cannot read pixels from the Surface part of the SurfaceView. The basic problem is that a Surface is a queue of buffers with a producer-consumer interface, and your app is on the producer side. The consumer, usually the system compositor (SurfaceFlinger), is able to capture a screen shot because it's on the other end of the pipe.
Take Screenshot of SurfaceView

Categories

Resources