Fastest way to continuously write bitmaps to disk - java

I have an android application and I am capturing every frame produced. I want to save each frame to disk. I know I could do video (i.e. using the MediaRecorder), but this is not what I want.
As you can imagine, writing 30 bitmaps to disk per second is pretty slow...
With the frames being produced at run-time, I do not know in advance how many will be produced.
Here is my write to disk function:
public static void store(Bitmap bm, String fileName){
File file = new File(fileName);
try {
FileOutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
What is the fastest way to save bitmaps to disk?

Related

Improving file save performance in android

I have 100 images on external memory which i do these two following tasks in a for loop .
Loading every item as a bitmap and merging it with another bitmap
Saving result in as a new file in memory
And for 100 images it takes too much time . Merging bitmaps is quit fast and OK but saving the result in file takes too much time . Is there anyway to boost this issue ? Keeping the bitmaps in memory and batch save files can cause OutOfMemoryException .
This is how i merge bitmaps :
how to merge to two bitmap one over another
This is how i save the bitmap to file :
File imageFileFolder = new File(Statics.TEMP_PATH);
imageFileFolder.mkdirs();
FileOutputStream out = null;
File imageFileName = new File(imageFileFolder, imageName);
try {
out = new FileOutputStream(imageFileName);
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Note that all of these are in a AsyncTask block .
Finally i came with the solution to save Bitmap as jpeg. Saving a 250k png bitmap took almost 500 milliseconds . The same bitmap in jpeg format took about 50 milliseconds. Although the qualities wont be the same but it looks like it is a tradeoff between quality and performance.

Display dicom in JavaFX button

I have many dicom (dcm) images that I want to display as thumbnails in my program. I can load it and draw in a separate window with ImageJ plugin:
try {
FileInputStream fis = new FileInputStream(dcms);
DICOM d = new DICOM(fis);
d.run(dcms);
d.setTitle(title);
d.show();
d.draw();
} catch (Exception e) {e.printStackTrace();}
}
But I want to be able to load it as a Image in a JavaFX button (as thumbnails) as I can do with pngs:
try{
Image picture = new Image(getClass().getResourceAsStream(dcms));
bt.setGraphic(new ImageView(picture));
}
I couldn't find any similar example on Google (most of the results lead to programs to convert the dicom to another thing through a program). But I don't want to convert and then display, I just want to display it.
Do you know if it's possible? Or will I have to convert it before loading the thumbnails?
EDIT : I know that I can save each picture somewhere e.g temp folder and then load it as a Image, but I still think that it's a unnecessary workaround. And I would like to avoid it if possible.
I found a way to use it:
FileInputStream fis;
try {
fis = new FileInputStream(path);
DICOM d = new DICOM(fis);
d.run(path);
Image picture = SwingFXUtils.toFXImage(d.getBufferedImage(), null);
Button bt = new Button();
bt.setGraphic(new ImageView(picture));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Posted because it might be useful for someone else.

Convert Image format in android java

How do i convert Image format from within my android application activity.
I have the code to convert image format using Java, but it doesn't output the image with good quality and also similar code is not working in Android's Java.
You didn't post any of your code, so i have no idea what is wrong with your code. but you can convert a image to PNG or JPEG like this:
try {
FileOutputStream out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); //100-best quality
out.close();
} catch (Exception e) {
e.printStackTrace();
}
For example, from Bitmap to JPG:
Bitmap bmp;
JPEG_QUALITY = 80;
bmp.compress(Bitmap.CompressFormat.JPEG, JPEG_QUALITY, out);

creating .bmp image file from Bitmap class

I've created an application that uses sockets in which the client receives the image and stores the data of the image in Bitmap class....
Can anyone please tell me how to create a file named myimage.png or myimage.bmp from this Bitmap object
String base64Code = dataInputStream.readUTF();
byte[] decodedString = null;
decodedString = Base64.decode(base64Code);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0,decodedString.length);
Try following code to save image as PNG format
try {
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
}
out.flush();
out.close();
Here, 100 is quality to save in Compression. You can pass anything between 0 to 100. Lower the digit, poor quality with decreased size.
Note
You need to take permission in Android Manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Edit
To save your image to .BMP format, Android Bitmap Util will help you. It has very simple implementation.
String sdcardBmpPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/sample_text.bmp";
Bitmap testBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_text);
AndroidBmpUtil bmpUtil = new AndroidBmpUtil();
boolean isSaveResult = bmpUtil.save(testBitmap, sdcardBmpPath);
try {
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}

streaming a jpeg using com.sun.image.codec.jpeg.JPEGImageEncoder vs javax.imageio.ImageIO

I have a BufferedImage object of a jpeg which needs to be streamed as servlet response.
The existing code streams the jpeg using JPEGImageEncoder which looks like this :
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(resp.getOutputStream());
resp.reset();
resp.setContentType("image/jpg");
resp.setHeader("Content-disposition", "inline;filename=xyz.jpg");
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
param.setQuality(jpegQuality, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(image);
I have noticed that this is resulting in the file size of the streamed jpeg to be tripled , unable to figure why.So I have tried using ImageIO to stream the jpeg
ImageIO.write(image, "jpg", out);
This works just fine, I am unable to decide why my predecessor has gone with the choice of JPEGImageEncoder and was wondering what issues would arise if I change to using ImageIO, I have compared both jpegs and couldn't really spot differences. Any thoughts?
To be clear, you've already a concrete JPEG image somewhere on disk or in database and you just need to send it unmodified to the client? There's then indeed absolutely no reason to use JPEGImageEncoder (and ImageIO).
Just stream it unmodified to the response body.
E.g.
File file = new File("/path/to/image.jpg");
response.setContentType("image/jpeg");
response.setHeader("Content-Length", String.valueOf(file.length()));
InputStream input = new FileInputStream(file);
OutputStream output = response.getOutputStream();
byte[] buffer = new byte[8192];
try {
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
finally {
try { input.close(); } catch (IOException ignore) {}
try { output.close(); } catch (IOException ignore) {}
}
You see the mistake of unnecessarily using JPEGImageEncoder (and ImageIO) to stream image files often back in code of starters who are ignorant about the nature of bits and bytes. Those tools are only useful if you want to convert between JPEG and a different image format, or want to manipulate (crop, skew, rotate, resize, etc) it.

Categories