11

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?

Swayam
  • 16,294
  • 14
  • 64
  • 102
Andrei Oniga
  • 8,219
  • 15
  • 52
  • 89
  • What Android version are you running? It works in Jelly Bean (4.1.1). I can generate the image from canvas and can save it without problems. – alex Sep 05 '12 at 18:31
  • can you try and see if creating a div with css style `background-image: url(data:image/png;base64datahere....);` works instead of creating a img with src? – Prasanth Sep 06 '12 at 04:32

2 Answers2

4

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();
            }
        }
    }
}
Robert
  • 14,999
  • 4
  • 39
  • 46
Ty Smith
  • 2,594
  • 2
  • 23
  • 29
  • Very nice solution. This kind of solution always provide a full control development model to the project team, allowing you to treat the exception to fix it and keeping the default way when the exception isn't needed to be treated. But I think this seems to be a good approach if, and only if, backward compatibility is your focus too. – Miere Sep 07 '12 at 14:45
  • @Ty S. What language is this exactly? I can't tell. – Andrei Oniga Sep 11 '12 at 09:01
  • Java on the Android platform. – Ty Smith Sep 11 '12 at 14:44
  • To my understanding, this solution is applicable only on the smartphones with the applied software modification, is this right? – Andrei Oniga Sep 11 '12 at 18:44
  • This is specific to a native Android Application on the device. – Ty Smith Sep 11 '12 at 19:33
  • I'm afraid this isn't feasible. If there's a way to achieve what I'm looking for, it has to be applicable on all devices. After all, this web app is not intended to be used on a singular mobile device. – Andrei Oniga Sep 12 '12 at 11:32
1

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

Community
  • 1
  • 1
Kuitsi
  • 1,675
  • 2
  • 28
  • 48