How to manipulate canvas element in HTML5? - html

Consider if two boxes on each side, the boxes will have 5 entries each, the left boxes we have animal names like dog,cat,tiger,elephant,monkey. The right will have milk,goat,coconut,bones,banana.
Now using the canvas element i need to map these 2 box elements and save the result in Database and i need to retrieve it again the next time as well.
How do i implement this one?
Thanks in advance..

If you want to save your canvas to a database, then you'll need to convert the canvas to a Base64 string and then save this string to the database like this:
<input type="text" name="mybase64" />
<script type="text/javascript">
function saveClicked() {
var dataURL = document.getElementsByTagName("canvas")[0].toDataURL("image/jpeg");
$("input[name=\"mybase64\"]").val(dataURL);
}
</script>
You will then post this mybase64 to whatever web service / code behind page that will received and write this string to your storage medium. To redraw the image to the canvas, you would get your base64 string from your DB and write it to the canvas like this:
function drawCanvas(myBase64String) {
var canvas = document.getElementsByTagName("canvas")[0];
var context = canvas.getContext("2d");
var image = new Image();
image.src = myBase64String;
image.onload = function() {
context.drawImage(image, 0, 0);
}
}
The main answer to your question is, if you want to store your canvas to a database it MUST be done in base64 form.

Related

How to Create an Image from Rectangle

I need the ability to be able to create an image of size 400x400 on the fly in a Windows Phone app, which will have a color of ARGB values that a user selects from a color picker. For instance, the user will click on a HyperlinkButton to take them to a ColorPickerPage and then will select a color, and I will retrieve that value and create the image from it, and display this image back on the MainPage. How might something like this be accomplished one I have retrieved the ARGB value from the user? I have not had luck finding any resources on this particular issue.
EDIT**
I came across http://www.geekchamp.com/forums/windows-phone-development/how-to-correctly-save-uicontrol-with-opacity-to-writeablebitmap which creates a rectangle on the screen and then saves to WriteableBitmap, but how might I skip that step and just save the Rectangle to WriteableBitmap? Note, I only have a single rectangle that I Fill with a custom Color.
You can save any UI element as an image using the code below. Here rect is the name of the rectangle in your XAML. If the rectangle isn't present in the UI then simply create one using C#. I have added the code to create a rectangle using C# and commented it.
public void saveimage(int height, int width, String filename)
{
//Rectangle rect = new Rectangle();
//rect.Height = 40;
//rect.Width = 40;
//rect.Fill = new SolidColorBrush(System.Windows.Media.Colors.Cyan);
var bmp = new WriteableBitmap(width, height);
bmp.Render(rect, null);
bmp.Invalidate();
var isf = IsolatedStorageFile.GetUserStoreForApplication();
if (!isf.FileExists(filename))
{
using (var stream = isf.OpenFile(filename, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
bmp.SaveJpeg(stream, width, height, 0, 100);
stream.Close();
}
}
}
Did you try using the Drawing Class.
here's the reference from msdn.
These are some samples: System.Drawing and System.Drawing.Imaging alternatives for Windows Phone
http://code.msdn.microsoft.com/windowsapps/Multi-Touch-Drawing-744a0b48
Hope it helps!

html5 canvas drawing / saving

I'm attempting to turn the html5 canvas into a slide annotator. My goal is to upload an Image of a slide, allow the user to draw on it, and then save it.
Whats working: I successfully have slides being uploaded as background images and allowing the user to draw on them. I also have the save function working.
Whats wrong: Once the image is save, the drawing the user made stays but the background image doesn't become part of the saved image.
Is there a way to save the canvas to an image and keep the slide background in it? Perhaps its not supposed to be a background image?
Here is some of my code:
The Canvas + button:
<div id="main">
<canvas id="drop1" class="drop" style=" background: url(pdf_images/pdf-save-0.png); background-repeat:no-repeat;">
</canvas>
</div>
<input type="button" id="savepngbtn" value="Save Slide">
Saving the Canvas:
document.getElementById("savepngbtn").onclick = function() {
saveCanvas(oCanvas, "PNG");
}
function saveCanvas(pCanvas, strType) {
var bRes = false;
if (strType == "PNG")
bRes = Canvas2Image.saveAsPNG(oCanvas);
if (!bRes) {
alert("Sorry, this browser is not capable of saving " + strType + " files!");
return false;
}
}
you will need to make the 'background-image' part of the canvas if you would like to save them as a single image.
you can try something like:
var ctx = yourcanvas.getContext('2d');
var img = new Image();
img.src = 'http://yourimage.png';
img.onload = function() {
ctx.drawImage(img, 0, 0)
}
then allow the user to add the annotations and save.
It shouldn't be a background image.
You should use the canvas's provided DrawImage to draw an image. It's pretty simple to do so, just create a new image element (ie. new Image(), set the onload event to call DrawImage with itself as a parameter and then set the .src attribute so that it actually loads).
Obviously this should be the first thing you do as the image is kindof paramount to how the canvas works. You could add an additional hook within onload so as to not allow the user to do any drawing until the image has loaded.

Should I use multiple images in one canvas?

What is best practice? Should I make a separate canvas tag for each image in html5, or is it just as functional to put multiple images in one canvas, and how would I do that.
My Code so far:
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
var cat = new Image();
cat.src = "images/cartoonPaul01.jpg";
cat.onload = function() {
context.drawImage(cat, 0, 0, 169, 207);
};
You can do this dynamically, if you're so inclined. muro from deviant art uses a few base canvases – temp, buffer, and background. Then you dynamically create and delete layers using a control on the side. It depends largely on what you want to do.
If you are just printing to the canvas, and you don't need to necessarily alter the images in a way that needs dynamism, you can draw them all to one canvas. If you need layering, use it.
Dynamic canvas and context creation:
// This is not best practice, just an example using globals.
var layers = [];
var lyrCtx = [];
createLayer = function() {
// Create the canvas.
layers.push(document.createElement('canvas'));
layers[layers.length - 1].setAttribute('id', 'layer'+layers.length-1);
// Create the context. Provided you do it in order, lyrCtx[i] should correlate to layers[i]
lyrCtx.push(layers[layers.length - 1].getContext("2d"));
// Handle context settings here.
}
You should get the balance. I usually use 4-6 canvas layers in my app, and draw logical part on them.

How do I generate a thumbnail client-side in a modern browser?

I'm looking for an elegant way to generate a thumbnail for use with the FileAPI. Currently I get a DataURL representing an image. Problem is, if the image is very large, than moving it around and rerendering it becomes CPU intensive. I can see 2 options to get around this.
Generate a thumbnail on the client
Generate a thumbnail on the server, send the thumbnail back to the client (AJAX).
With HTML5 we have a canvas element? Does anyone know how to use it to generate thumbnails from pictures? They don't have to be perfect -- sampling quality is acceptable. Is there a jQuery plugin that will do this for me? Are there any other way to speed up the clientside use of large images?
I'm using HTML5, and Firefox 3.6+: there is no need to support anything other than Firefox 3.6+, please don't provide suggestions for IE 6.0
Here’s what you can do:
function getThumbnail(original, scale) {
var canvas = document.createElement("canvas");
canvas.width = original.width * scale;
canvas.height = original.height * scale;
canvas.getContext("2d").drawImage(original, 0, 0, canvas.width, canvas.height);
return canvas
}
Now, to create thumbnails, you simply do the equivalent of this:
var image = document.getElementsByTagName("img")[0];
var thumbnail = getThumbnail(image, 1/5);
document.body.appendChild(thumbnail);
Note: Remember to make sure that the image is loaded (using onload) before trying to make a thumbnail of it.
Okay, the way I can see this working is drawing the image to the canvas at a smaller size, then exporting the canvas. Say you want a 64px thumbnail:
var thumbSize = 64;
var canvas = document.getElementById("canvas");
canvas.width = thumbSize;
canvas.height = thumbSize;
var c = canvas.getContext("2d");
var img = new Image();
img.onload = function(e) {
c.drawImage(this, 0, 0, thumbSize, thumbSize);
document.getElementById("thumb").src = canvas.toDataURL("image/png");
};
img.src = fileDataURL;
With this code, an image element with the id "thumb" is used as the thumbnail element. fileDataURL is the data URL that you got from the file API.
More information on drawing images to the canvas: http://diveintohtml5.info/canvas.html#images
And on exporting canvas data: http://msdn.microsoft.com/en-us/library/ie/ff975241(v=vs.85).aspx

How to convert bytearray to image or image to bytearray ?

How to assign bytearray value to panel background image. If anybody have idea or experiance plz help me to overcome the problem. BRIEF EXP:
I have panel control and want to load image getting from webservice as a backgroundimage. So i used setstyle() but its not accepting that image. so how to add that image into my panel background image.Plz tel me your ideas here.
In Flex 3 or higher, you just need to do:
yourImage.source = yourByteArray;
regards!
uhm, well i presume, since it is an image, you have it in a BitmapData, let's say "myBmp" ...
then use the following to extract all the data from BitmapData:
var bytes:ByteArray = myBmp.getPixels(myBmp.rect);
and the following to write:
myBmp.setPixels(myBmp.rect, bytes);
note that only the raw 32 bit pixel data is stored in the ByteArray, without compression, nor the dimensions of the original image.
for compression, you should refer to the corelib, as ozke said ...
For AS3 you can use adobe corelib. Check this tutorial...
http://ntt.cc/2009/01/09/as3corelib-tutorialhow-to-use-jpegencoder-and-pngencoder-class-in-flex.html
I used a flash.display.Loader() to load an image in an array. It has a Complete event that is fired after the image has been loaded. I then draw the image on to a Bitmap which I set to the data of a Image that could be placed in a panel. Hope you can make since of this good luck.
public static function updateImage(img:Image, matrix:Matrix,
pageDTO:PageDTO, bitmapData:BitmapData):void {
var loader:flash.display.Loader = new flash.display.Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (e:Event) : void {
bitmapData.draw(loader.content, matrix);
pageViewer.data = new Bitmap(bitmapData);
});
loader.loadBytes(pageDTO.thumbnail);
}
<mx:Panel>
<mx:Image id="pageViewer"/>
</mx:Panel>
Using adobe's JPGEncoder (com.adobe.images.JPGEncoder) class and ByteArray is pretty much all you need. Converting image to byte array (assuming CAPS are variables you'd need to fill in):
// -- first draw (copy) the image's bitmap data
var image:DisplayObject = YOUR_IMAGE;
var src:BitmapData = new BitmapData(image.width, image.height);
src.draw(image);
// -- encode the jpg
var quality:int = 75;
var jpg:JPGEncoder = new JPGEncoder(quality);
var byteArray:ByteArray = jpg.encode(src);
I had the same problem. As a workaround I created sub Canvas nested inside a main Canvas and added an Image to the main Canvas behind the sub Canvas. Anything drawn on the sub Canvas will appear on top of the Image.
Just load it into a Loader instance using the loadBytes function.
var ldr:Loader = new Loader();
ldr.loadBytes(myByteArray);
addChild(ldr);