Save HTML5 Canvas Image to Gallery – Phonegap Android plugin

Update

Readers of this post have raised issues with the plugin. I have to personally check for the issues but while using the plugin if you find any issues, you might want to debug it in ADT. I will come up with a working plugin soon. Thanks.

Sometime back I worked on a Phonegap Android plugin that helps to save an HTML5 Canvas Image to the device’s gallery. Well, the title of this post may be misleading but note that when you save an image, you actually have to save it on the SD Card or the device’s memory. The Gallery is just an app that shows the collection of images from various locations on the SD Card. So, there’s nothing like saving an image directly to the Gallery.
I had this working with Phonegap 2.2.0 (the version that I used). Newer versions of Phonegap/Cordova are available and things might have changed a bit, specially in the way custom plugins are written. Hence, if you are using newer versions of Phonegap you should have a look at the official documentation before proceeding.
Alright, here is what I did. I tried to save an image using the FileWriter – Phonegap API, but as it turned out, it can save only text data on the device’s memory. So, only way to do it was write a Phonegap plugin, pass the Canvas details from JavaScript interface to the Java side and let the Java class save the Canvas image on the SD Card.
Note that I am not a Java developer, and there may be better ways of writing this plugin.

How to install the plugin?
You need to get hold of two files :
1) The Java class – SavePhotoPlugin.java
2) The JavaScript interface – SavePhotoPlugin.js

Read More »

Advertisements

Replicating the iPhone Swipe Gesture – Vertical swiping

For those who wanted a vertical swiping feature to the the swipe gesture gallery that I created earlier, this post has a new demo and minimal explanation about a vertical swipe gesture gallery. Now you can swipe the images up or down.
I will not go through the basics once again as I have explained them in details in my previous posts. You can refer them once again in these two tutorials – post 1, post 2. Check out the demo below. Open the link in a webkit browser in either your mobile device or your computer.

Demo link: http://rialab.jbk404.site50.net/swipegesture/vertical/

Below is a screenshot of the gallery in action. You can see that the images are being moved vertically.

Screenshot of vertical swiping through images
Screenshot of vertical swiping through images

Read More »

Saving Image to Android device’s Gallery – Phonegap Android

Update
Save HTML5 Canvas Image to Gallery – Phonegap Android plugin
I have a Phonegap Android plugin that helps to save HTML5 Canvas Image to the Gallery. See it here.

Now, back to the actual post,

Quick snippet of code that will help a Phonegap Android app to save an image to the Android device’s SD Card and make it available to the Gallery app to show. The title of this post may be misleading but note that when you save an image, you actually have to save it on the SD Card or the device’s memory. The Gallery is just an app that shows the collection of images from various locations on the SD Card. So, there’s nothing like saving an image directly to the Gallery.

Moreover I tried to save an image using the FileWriter – Phonegap API, but as it turned out, it can save only text data on the device’s memory. So, only way to do it was write a Phonegap plugin, pass the image data from JavaScript interface to the Java side and let the Java class save the image on the SD Card. Well I am not going to talk on the entire plugin, but I will share the Java code,

The methods below should be included inside your plugin’s Java class. The idea is simple, whatever be your image/ image data (eg. Base64 data), you take that image data and save it on the SD Card using the FileOutputStream. You get the file path by querying the external storage public directory which is the first line inside the savePhoto() method below. Now, after the image is saved you broadcast it through the System’s Media Scanner so that it becomes available to the Android Gallery app and to other apps. Hope this is clear, time for action now.

private String savePhoto(Bitmap bmp)
{
  //File imageFileFolder = new File(Environment.getExternalStorageDirectory(),"MyFolder"); //when you need to save the image inside your own folder in the SD Card
  File path = Environment.getExternalStoragePublicDirectory(
     Environment.DIRECTORY_PICTURES
  ); //this is the default location inside SD Card - Pictures folder
  //imageFileFolder.mkdir(); //when you create your own folder, you use this line.
  FileOutputStream out = null;
  Calendar c = Calendar.getInstance();
  String date = fromInt(c.get(Calendar.MONTH))
  + fromInt(c.get(Calendar.DAY_OF_MONTH))
  + fromInt(c.get(Calendar.YEAR))
  + fromInt(c.get(Calendar.HOUR_OF_DAY))
  + fromInt(c.get(Calendar.MINUTE))
  + fromInt(c.get(Calendar.SECOND));
  File imageFileName = new File(path, date.toString() + ".jpg"); //imageFileFolder
  try
  {
    out = new FileOutputStream(imageFileName);
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
    out.flush();
    out.close();
    scanPhoto(imageFileName.toString());
    out = null;
  } catch (Exception e)
  {
    e.printStackTrace();
  }
  return imageFileName.toString();
}
private String fromInt(int val)
{
  return String.valueOf(val);
}

/* invoke the system's media scanner to add your photo to the Media Provider's database,
* making it available in the Android Gallery application and to other apps. */
private void scanPhoto(String imageFileName)
{
  Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  File f = new File(imageFileName);
  Uri contentUri = Uri.fromFile(f);
  mediaScanIntent.setData(contentUri);
  //this.cordova.getContext().sendBroadcast(mediaScanIntent); //this is deprecated
  this.cordova.getActivity().sendBroadcast(mediaScanIntent); 
}

Note that I am not a Java developer, and you may need to modify this code as per your needs. But it should work. First save your image (create a Phonegap Android app and test it) and after that you can see it being displayed in the gallery app. I did collect this code by browsing the net and made it work 100%. Otherwise it was difficult for me, since I did not find any concrete answer on this. Leave a suggestion if there is a better solution.

HTML5 Canvas – toDataURL() support for Android devices – working Phonegap 2.2.0 Plugin

Update
Save HTML5 Canvas Image to Gallery – Phonegap Android plugin
I have a Phonegap Android plugin that helps to save HTML5 Canvas Image to the Gallery. See it here.

Back to the actual post,

I have been working on a Phonegap based Android app which involves the HTML5 Canvas. So this is what I had been trying for some time – get a png/jpeg image of the Canvas (its a Canvas paint app, something like this and I want to get an image of the drawing..) and then upload the image to Facebook on a user’s album. Let me tell you, it has been a heck of a task and around 15-20 days of restlessness.

The problem stood tall when I discovered that for Android 2.3 (in general Android < 4.0) devices the native HTML5 Canvas- toDataURL() function does not work, which would otherwise give a base64 encoded string  as image data which then can be used as a source for a HTML <img /> tag. It was working for 4.0 devices as I tested it on a Samsung Galaxy S3 and a Samsung Tab. Hence I Goggled a bit and found out various people had this issue before. So it seemed that older Android web-kits (a Phonegap app runs on the Android webview which is actually the webkit browser inside a native wrapper) does not support that native method of converting a Canvas to an image through toDataURL() generated base64 encoded strings. Guess what I had todo? I had to go for a custom Phonegap plugin as there was no other way. This is how I thought of implementing it – pass the canvas object from javascript side to the Phonegap plugin’s Java class and somehow get the base64 encoded string of the Canvas and return it back to javascript as the callback parameter. This is what the native toDataURL() method actually does – convert the Canvas to a base64 encoded image data string.

Read More »

Replicating the iPhone Swipe Gesture – auto scrolling feature

This is an update to the Replicating touch swipe gesture javascript implementation series that I have been writing for some time now and this time I have tried out the auto scrolling feature. Sometimes users may want a auto scrolling along with the normal swipe gesture feature. This post will talk about it and the changes to code that were made to make it auto scroll. First let’s check out the demo, the demo runs in both computer webkit browsers and mobile webkit browsers.

Demo link: http://rialab.jbk404.site50.net/swipegesture/auto_scrolling/

Now, let’s talk on the implementation,
First the features of this demo-

  • Auto scrolling – the gallery slides change automatically at periodical times. Based on the requirement specify whether auto scroll stops on user interaction or continues.
  • Looping – the gallery loops and is circular.
  • Direction – supports two direction – left or right. Specify which direction the gallery should auto scroll.
  • Click/Tap to URL – click or tap to open URL’s.
  • Swipe gesture – and then the touch based swipe gesture for mobiles is available as well.

Read More »

Circular swipe gesture gallery – looping through images

This is another update to the regular swipe gesture gallery that I created in two of my earlier post – post1, post2. This time I have implemented the looping feature for the images. The gallery never ends, instead you swipe it in a circular motion. So, whenever you reach the end of the list, swipe again from right to left across your device’s screen to see the first image and also when you reach the beginning of the list you swipe from left to right of your device’s screen to see the last image again. Try out the demo first and you will get a feel of it. Check out the demo in a webkit desktop browser (Chrome, Safari) or an iOS/Android device’s browser. Click on any image to open a URL as well. So, click/tap to open URL is included.

Demo link: http://rialab.jbk404.site50.net/swipegesture/circular/

An instance of the demo application – with reduced opacity and exposed images, the darker one being the one currently displayed and is inside the wrapper div.

Read More »

Replicating the iPhone Swipe Gesture – common code for mobiles and computer browsers.

This is another update for the iPhone Swipe Gesture that I have created. This is the third update to the series – Part 1 and Part 2. In case you have missed out of the earlier tutorials and detailed explanation then you can have a look at them first, before proceeding with this tutorial. What I have been able to achieve is that, I have replicated the native iPhone swipe gesture for the iPhone web-kit browser. So, throughout the series I have been able to create a HTML/JavaScript/CSS3 version of the swipe gesture. If in case, again you are not sure of the swipe gesture and swiping, I would recommend to go through my previous tutorials – Part1 and Part2.

Now, the update and the agenda of this tutorial is that – I have developed a common universal code for mobile browsers and computer browsers. Note that when I am saying browsers I mean web-kit browsers – Chrome & Safari in computers, and then the default web browsers in iOS and Android mobiles. The major changes are in the javascript code, where I have automated the user event handling process. What this means is that for mobile devices touch based events are registered and listened to and then for computer browsers mouse based events are registered and handled by the script automatically. This way there is no need to hard code touch events for mobiles and mouse events for computers. The same code works everywhere.

But, still to support different device screen sizes you will need to make changes to the CSS or the asset (images) sizes. The demo that I have worked on, I have considered the iPhone resolution – 320 x 416.

Check out the demo (same link works in mobiles and computers): http://jsphkhan.github.io/swipe_gesture_common/

An image/slide showing up in portrait mode
Common implementation for mobiles and computers

Read More »

Replicating the Swipe Gesture iPhone Gallery for mobile web – images linked to URL

Just a quick update. I have made little changes to the original demo so that now the images are clickable or rather tap-able. So when a user taps on an image he is redirected to a URL. You can specify separate URL’s of your choice for each image. The default behavior of the swipe gesture and replicating it is still there. I have just added the feature of linking the images to URL.

Try the demo in computer or mobile browser (webkit based browsers only): http://rialab.jbk404.site50.net/swipegesture/common/

Tap/Click on any image in the gallery to open a URL. Also you can swipe on the images.

What are the changes made?
On the HTML side, I added the URL’s to the <img /> element in the index.html file, I have added a custom attribute link.

<li>
<img src="img/1.jpg" width="100%" height="100%" link="http://www.google.com"/>
</li>
<li>
<img src="img/2.jpg" width="100%" height="100%" link="http://www.yahoo.com"/>
</li>

Similarly, all the other <img /> elements have a link attribute that specifies the URL to redirect when user taps on that particular image. Note that link is a custom attribute. You can add custom attributes to HTML elements.

On the script part
This is where a little understanding is required. In my previous posts – part1 and part2 I have discusses in details about the swipe gesture and how using touch events I have managed to achieve it. If you see the JavaScript code, I have registered touch events that listen to the user’s finger movements. So if you notice a swipe gesture is actually a combination of

Swipe Gesture = touch start + touch move + touch end

It is only in the touch end event listener that we manipulate the net distance moved and based on that we swipe the images. Now, since we also need a tap/click to URL feature for each image so if you directly add a redirection code in either touchstart or touchend event listeners then every time you try to swipe it will take to to a URL. And then even the swipe is affected. So as soon as you start to swipe it, it will redirect you to a URL, which is exactly what we do not want. Now, if you notice a tap event it is a combination of,

Image Tap (Tap to a URL) = touch start + touch end

So there is no touch move in a tap event for an image. So this is the concept that helps in making the Swipe as well as the Tap to URL work together. When a user swipes across the screen he is actually covering some net distance, so your start point is not same as the end point. But when you tap on an image your start point and end points are same before you release your finger. Hence in a tap the net distance is zero. So based on that I made changes to the event handler for touchend event in the script file,

swipey.wrapper.addEventListener("touchend", swipey.endHandler, false);

And then in the endHandler method I added this,

if(swipey.distanceX == 0) //if the intention is to tap on the image then open a link
{
  var link_url = event.target.getAttribute("link"); //read the link from <img /> element
  window.open(link_url,"_blank");
}

This checks if the net distance is zero. And if it is so, then it reads the link attribute value and then redirects the user to the URL specified by link.

To open links/URL in same window or page – use _self instead of _blank in window.open()

This is it, now the code is capable to handling both user swipes and user tap/click to URL. You can checkout the demo. To download the code follow the link given below.

Download code
You can download the source code here.

Updates/Other related posts
1) Creating a swipe gesture gallery – My initial post on the topic. You can start here.

2) Flickering issue in iPhone/iPod solved.
After the swipey demo was done I was observing a strange flickering issue of the images. If you see the demo link in an iPhone or iPod’s mobile safari browser you would notice it. Test case – swipe the images to the left and you would notice a black flicker on the right side of the browser for a brief moment. This is happening when you swipe all the image for the first time. Second time on wards it is not being seen. Finally I could solve the issue and made a small post on it with the new fixed demo. You can find it here.

3) Common code and example for mobiles and computer browsers – I have developed a common universal code for mobile browsers and computer browsers. Note that when I am saying browsers I mean web-kit browsers – Chrome & Safari in computers, and then the default web browsers in iOS and Android mobiles. The major changes are in the javascript code, where I have automated the user event handling process. What this means is that for mobile devices touch based events are registered and listened to and then for computer browsers mouse based events are registered and handled by the script automatically. This way there is no need to hard code touch events for mobiles and mouse events for computers. The same code works everywhere. Find the post here. There is a demo and also a download link.

4) Circular swipe gesture gallery – I have a new tutorial where I have talked about a circular swipeable gallery. So the images keep on looping. The tutorial also includes a new demo. Read it here.

5) Auto scrolling swipe gesture gallery – Sometimes users may want a auto scrolling gallery along with the normal swipe gesture feature. I have a new post with a demo. Read it here.

Replicating the Swipe Gesture iPhone Gallery for mobile web– HTML5 – flickering issue fixed

The swipe gesture image gallery that we talked about in one of the earlier post had a strange flickering issue. There was a slight flickering of the image that was being swiped along with the movement of finger. I observed the flickering mostly in iOS devices – iPhone, iPod touch and iPad’s.
After a lot of head scratching and looking around in forums I finally got a solution. One of the guys (he is divine for me now) in StackOverflow suggested to add two lines of CSS to all the elements that moved using CSS3 transition. I tried it out and guess what, it worked!. I just added two lines to the CSS style for the images. This is what solved it,

#wrapper ul li img
{
  -webkit-backface-visibility: hidden;
  -webkit-perspective: 1000;
}

Add this style block to the CSS file and the issue will be a gonner. The link to the fixed demo is below (I have merged the fix with the original demo. So there is no separate demo). Check out in an iOS device’s browser. Note that the demo’s run in an Android browser as well. But I observed the flickering in iOS devices only.

http://jbk404.site50.net/html5/mobile/swipey/mobile_version/

Also try removing the above CSS lines and checking out the demo again. You will notice flickering.

Updates/Related posts

1) Images linked to URL – Now you can click or tap on the images to go to a URL. I have made a new post which describes the changes made. This was requested by one of the reader. I felt the importance of having the ability to link the images to URL so came up with an extension of this post. You can fine the post here. There is a demo and also a download link.

2) Common code and example for mobiles and computer browsers – I have developed a common universal code for mobile browsers and computer browsers. Note that when I am saying browsers I mean web-kit browsers – Chrome & Safari in computers, and then the default web browsers in iOS and Android mobiles. The major changes are in the javascript code, where I have automated the user event handling process. What this means is that for mobile devices touch based events are registered and listened to and then for computer browsers mouse based events are registered and handled by the script automatically. This way there is no need to hard code touch events for mobiles and mouse events for computers. The same code works everywhere. Find the post here. There is a demo and also a download link.

3) Circular swipe gesture gallery – I have a new tutorial where I have talked about a circular swipeable gallery. So the images keep on looping. The tutorial also includes a new demo. Read it here.

4) Auto scrolling gesture gallery – Sometimes users may want a auto scrolling gallery along with the normal swipe gesture feature. I have a new post with a demo. Read it here.