Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render Image as Data stream in Android browser

I put together a small test web app that converts an HTML canvas to an image (by using Nihilogic's canvas2image JavaScript library), then replaces the canvas with the generated image and displays a message notifying the user to touch (long) that image in order to save it to their phone.

The problem I came across is that Android's default web browser ("Internet") doesn't render the base64 encoded data stream that represents the image, but displays a question mark sign instead. Is there a way to resolve this? If yes, then how?

like image 389
Andrei Oniga Avatar asked Aug 24 '12 16:08

Andrei Oniga


2 Answers

Use a custom ContentProvider and override openFile() to return the stream as a Tempfile.

You can use the URI as the src in the html A tag.

<a src="Example://file"></a>
public class ExampleProvider extends ContentProvider {

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {         
        //Get your bitmap
        Bitmap bmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.file_example);
        File tempFile = null;
        try {
            //Create the tempfile form a stream
            tempFile = File.createTempFile("tempfile", ".thumb", getContext().getCacheDir());
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile));
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.close();
            if(mode.equals("r")) {
              return ParcelFileDescriptor.open(tempFile, ParcelFileDescriptor.MODE_READ_ONLY);
            }
        }
        catch(IOException e)  {
            LOGGER.error("Couldn't generate temp file for thumb view, guid:" + guid, e);
        }
        finally {
            if(tempFile != null {
                //The unix filesystem automatically deletes the file once all handles are gone
                tempFile.delete();
            }
        }
    }
}
like image 112
tsmith Avatar answered Oct 14 '22 13:10

tsmith


Based on comment of @goldenparrot image can be seen with

<img src="data:image/png;base64,BASE64_STRING_HERE" />

(and also with suggested css background-image) when base64 data is already present when page is loaded. However, it does not work for some reason when exactly the same data string is inputted dynamically. Even statically loaded image with base64 data has problems: it does not react to long click in any way, so it can't be downloaded. I'm using Android 2.3.6.

Edit: You can also try adding additional download link

<a href="data:application/octet-stream;base64,BASE64_STRING_HERE">download file</a>

but it didn't work for me. Android did just show contents of that file as text. Normal desktop web browser did open "download file" dialog but did not suggest any extension for that file, so user must add it manually.

See also Browser/HTML Force download of image from src="data:image/jpeg;base64..."

My test html page is http://kuitsi.bitbucket.org/stackoverflow12113616.html

like image 40
Kuitsi Avatar answered Oct 14 '22 13:10

Kuitsi