1

I am trying to convert a DIV to single image. The div has 4 images in it. I have found the js for "htmltocanvas" but this jquery plugin does not create image with all images present in the div.

Here is the div code which having the images in it and need to be convert into image.

<div id="myJershy">
    <!-- Color 3 -->
    <img src="grey.gif" id="grey" style="position: fixed; top: 8px; left: 12px; width: 935px;">
    <!-- Color 2 -->
    <img class="orange" id="orange" src="orange.gif" style="position: fixed; left: 10px; top: 8px;">
    <!-- Color 4 -->
    <img src="gold.gif" id="gold" style="position: fixed; top: 12px; left: 22px;">
    <!-- Color 1 -->
    <img class="back" id="black" src="back.gif" style="position: fixed; left: 11px; top: 9px;"> 
    <!-- outline -->
    <img class="skel" id="skel" src="outline.gif" style="position: fixed;">
</div>

I have also tried with the below javascript code but not able to get the success.

var htmlcontent = $("#myJershy").html();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
             "<foreignObject width='100%' height='100%'>" +
               "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
        htmlcontent+
               "</div>" +
             "</foreignObject>" +
           "</svg>";

var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
};
document.getElementById('previewproduct').src = url;

Please note "html div" has multiple images.

6
  • 1
    So basically you are trying to merge your images to one? Commented Feb 4, 2014 at 10:09
  • Yes, I need to merge all images. Is there another option do it with javascript? Commented Feb 4, 2014 at 10:09
  • Why dont you do that in Photoshop? Commented Feb 4, 2014 at 10:10
  • Yes, we can do it using photoshop, but I want this functionality in web page. And for your information these images are presented in web as one image. The image formed using all four image need to sent to server. Hence I want this functionality. Commented Feb 4, 2014 at 10:11
  • @user3270303 i will make a fiddle but it will take time.Check later Commented Feb 4, 2014 at 10:14

3 Answers 3

1

Here's my attempt:

http://jsfiddle.net/8FFQM/1/

Don't worry about those huge codes in the html, they're just the images url-encoded, you don't have to do it if your images are hosted on your domain.

The exported image as jpg is the one with red boarder (scroll around in the result window):

var DivsToJPG = function( parent ) {
    this.canvasSizeX = 0;
    this.canvasSizeY = 0;
    this.init = function( parent ) {
        this.images = parent.find('img');
        this.setSizes();
        this.createCanvas();
        this.drawImages();
        this.exportJPG();
    }

    this.setSizes = function() {
        for (var i = 0, l = this.images.length; i < l ; i++) {
            var currentImage = this.images.eq(i);
            var posX = currentImage.position().left;
            var width = currentImage.width();
            this.canvasSizeX = this.canvasSizeX > (posX+width) ? this.canvasSizeX : posX + width;
            //console.log(this.canvasSizeX);
            var posY = currentImage.position().top;
            var height = currentImage.height();
            this.canvasSizeY = this.canvasSizeY > (posY+height) ? this.canvasSizeY : posY + height;

         }
    }

    this.createCanvas = function() {
        this.canvas = document.createElement('canvas');
        this.canvas.id     = "exportCanvas";
        this.canvas.width  = this.canvasSizeX;
        this.canvas.height = this.canvasSizeY;
        this.ctx = this.canvas.getContext("2d");
        document.body.appendChild(this.canvas);
    }

    this.drawImages = function() {
        for (var i = 0, l = this.images.length; i < l ; i++) {
            var currentImage = this.images[i];
            var $currentImage = this.images.eq(i);
            this.ctx.drawImage(currentImage, $currentImage.position().left, $currentImage.position().top, $currentImage.width(), $currentImage.height());
        }
    }

    this.exportJPG = function() {
        var dataURL = this.canvas.toDataURL();
        this.img = document.createElement('img');
        this.img.id = "createdImage";
        this.img.src     = dataURL;
        document.body.appendChild(this.img);
    }

    this.init( parent );
}

var divsToJPG = new DivsToJPG($('#myJershy'));

PS: it's a bit longer but it should take care of everything, it uses a bit of jQuery

Sign up to request clarification or add additional context in comments.

9 Comments

It's working....great code. Just there is one issue. When the new image get generated from the html DIV, the output doubled. I mean to say it replicate the div twice. Whereas we want only one. Can you please look over it.
You can just remove the elements needed to create the final image: jsfiddle.net/8FFQM/5 this.container.remove(); this.canvas.remove();
Please note, you might need to change this line: document.body.appendChild(this.img); to fit your needs if you want to append the final image inside another div or something else
cool, if you decided to use my answer, could you please accept it? thanks
sure, it's my pleasure. Here is the updated code. jsfiddle.net/pankaj_javascript/jykyh
|
0

See this fiddle


jQuery

var s=0;
$('#myJershy').children('img').each(function(){
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    var img=document.getElementById($(this).attr('id'));
    ctx.drawImage(img,s,10,$(this).width(),$(this).height());
    s=s+$(this).width();
});

If you want that the position of divs in canvas should be exactly as displayed outside canvas then see the below fiddle:

Fiddle 2

7 Comments

How can you not get the cross-domain policy issue when drawing images on the canvas?
sorry I got confused, you can draw images from another domain on a canvas, but you can't call toDataUrl() on the canvas with cross domain images on it. I have it in my answer and that's why I had the warning in the console.
A small note, I think this solution might create a problem when the images are below the screen size (if you have to scroll to see them) because of the offset()
The code is good one but it do not manage the css of div. As you can see in example html all images are arranged using css. In your code these css are not get in consideration. So the output image is just merge of all images present in the div. But we need code with css to.
@user3270303 did you check my second fiddle?
|
0

Here is my answer (based on @Zwords awesome answer) which takes the Top and Left positions into account. In case you want to layer those images.

$('#myJershy').children('img').each(function(){
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    var img=document.getElementById($(this).attr('id'));
 ctx.drawImage(img,$(this).css('left').replace('px',''),$(this).css('top').replace('px',''),$(this).width(),$(this).height());
});

Forked Fiddle from @Zword

2 Comments

But this will give same output as mine
Not exactly. Look at the style definitions in the html part of the question and my approach. I guess he wants to mount overlapping images. Nonetheless your Answer is perfectly right and rep should go to you. I just replaced coordinates with the defined css values and removed the 'px' part from the result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.