I am dealing with an AR application in Android that uses camera output. I'm working on a piece of code to save three image files: a raw image, a screen overlay, and a composite image with an overlay overlay (maybe redundant, given the other two). The native image size for my camera is 2592x1944.
Now my save operation takes longer than I would like. I am doing an image save using AsyncTask, but the actual part of saving comes down to the following:
public void onPictureTaken(byte[] data, Camera camera){ Size sz = camera.getParameters().getPictureSize(); TimingLogger tl = new TimingLogger("CodeTiming", "Start Saving"); String fileName = getNameFromTime(); tl.addSplit("Start Pic Save"); // The Picture itself ImageFile photo = new ImageFile(fileName+"_image.jpg"); photo.write(data); tl.addSplit("Start Overlay Save"); // The overlay with blank background Bitmap bmp = Bitmap.createBitmap(sz.width,sz.height,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); DrawStuffOnCanvas(canvas); ImageFile overlay = new ImageFile(fileName+"_overlay.png"); overlay.write(bitmapToByteArray(bmp,Bitmap.CompressFormat.PNG)); tl.addSplit("Start Overlay Onto Pic Save"); // The picture with the overlay drawn on Options options = new Options(); options.inDither = false; options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length, options); picture = picture.copy(Bitmap.Config.ARGB_8888, true); Canvas canvas2 = new Canvas(picture); DrawStuffOnCanvas(canvas2); ImageFile overlay2 = new ImageFile(fileName+"_combo.jpg"); overlay2.write(bitmapToByteArray(picture,Bitmap.CompressFormat.JPEG)); tl.addSplit("Start Metadata Save"); //Save picture metadata, not relevant to question tl.addSplit("Done"); tl.dumpToLog(); }
The conversion of the bitmap to byte [] is performed using:
byte[] bitmapToByteArray(Bitmap b,Bitmap.CompressFormat fmt){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); b.compress(fmt, 100, baos); return baos.toByteArray(); }
Please note that all file objects (for example, ImageFile) are customizable, but the necessary information is necessary to process the byte [] record using FileOutputStream. Here is a recent time dump for this run.
Start Saving: begin Start Saving: 4 ms, Start Pic Save Start Saving: 86 ms, Start Overlay Save Start Saving: 3576 ms, Start Overlay Onto Pic Save Start Saving: 2066 ms, Start Metadata Save Start Saving: 15 ms, Done Start Saving: end, 5747 ms
There is quite a bit of variability, somewhere around 5-15 seconds per save. Overlays (essentially the lines drawn on the screen) are currently saved as PNGs for transparency and due to artifacts at the sharp edges of the lines caused by JPEG compression. Following the logic of this question , I saw that if I switch the overlay to JPEG, I will reduce my time by this step in half. As you can see, I implemented this change for a composite image (sharp edges are already blurred by the image itself), which saved about 20 seconds in this compression step.
So my question is this. Is there anything I can do to save time on overlay compression but save PNG output? Or, alternatively, is there anything else I am doing here, spending a lot of time to speed up the general save operation? Then I would not have to worry about PNG and JPEG.