Is it possible whether with JS or jQuery to take an image, make it fit a container proportionally if it's too big for the container, then export the results to a PNG image, saving the step of redoing the image from scratch in a smaller image size ?

Recommended Answers

All 10 Replies

You could create/resize it on an HTML canvas and export the canvas to PNG using canvas.toDataURL("image/png").

Strictly one line of code, I have to run on a blank HTML page ?

A little more than that. The image has to be resized and drawn onto the canvas, then you can export the canvas to a data url with that function.

Perhaps these links will help:

resizing proportionally

drawing to canvas

I reckon a combination of those should do it.

I've never used Canvas, this will be more of a utility, if I can use it for that, create a container, make the container the size I want, place the image in the container, run the script, get the image, place it into the container. Why isn't the image proportionally fitting to the container, I'm not sure if canvas will fix strectching unless it can do smart interpolation to the image to make it looks propotionally correct ?

[Link]

If I use

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
    imageObj.src = 'img url snipped';
    imageObj.onload = function() {
        var width = 200;
        var height = imageObj.height * (width/imageObj.width);
        canvas.width=width;
        canvas.height=height;
        context.drawImage(imageObj, 0, 0, width, height);
    };

And remove the bottom:50px; from that css, I get:

2015-01-15--1421308160_636x334_scrot.png

If I then right click and "view image" it shows the image in a smaller version without the white space. Saving works too and produces a smaller image. You'll just need that export to png part (and add the image url I snipped). And perhaps fetch the image width from canvas.width instead of the other way around.

Not sure if the fiddle updated, but just in case.

The image is not fitting the width nor the height of the container, as in completely convering the blue container at the same time keeping the image proportioned so there is not any stretching in height or width, unless I'm missing something ? :)

Just out of curiosity... why aren't you just using CSS to size the image to fit the container?

#myImg { width:auto; max-width:100%; }

I thought: given an arbitrary width (whether it comes from a div, canvas or in my example 200) adjust the height proportionally, write it to a canvas of the same size so it can be exported as PNG in the new size.

Just out of curiosity... why aren't you just using CSS to size the image to fit the container?

The image has to be written to canvas if you want to export it to PNG using canvas.toDataURL("image/png"). Can CSS influence an image inside a canvas? Perhaps set the height/width of the image with CSS, then retrieving the width/height to write it on the canvas. But will that work with auto and %? No idea, just pondering as well.

The image is not fitting the width nor the height of the container

Well no, that seemed something you could do, alter the 200 to whatever size the div is. But, I realized height would never be adjusted in my example so I dove in one more time.

        var canvas = document.getElementById('myCanvas');
        var container = document.getElementById('one');
        var context = canvas.getContext('2d');
        var imageObj = new Image();
            imageObj.src = 'darth-vader.jpg';
            imageObj.onload = function() {
                var size = fetchSize(imageObj.width,
                                     imageObj.height,
                                     container.offsetWidth,
                                     container.offsetHeight);
                canvas.width=size[0];
                canvas.height=size[1];
                context.drawImage(imageObj, 0, 0, size[0], size[1]);
            };

        function fetchSize(w,h,max_w,max_h){
            var size = [w,h];
            var r;
            if(w > max_w){
                r = max_w / w;
                size[0] = max_w;
                size[1] = h * r;
                h = h * r;
                w = w * r;
            }
            if(h > max_h){
                r = max_h / h;
                size[1] = max_h;
                size[0] = w * r;
            }
            return size;
        }

This will give the following results using a 438 x 300 image:

A 200 x 200 div:

2015-01-15--1421339880_872x331_scrot.png

A 400 x 800 div:

2015-01-15--1421339953_852x585_scrot.png

A 800 x 200 div:

2015-01-15--1421340074_877x306_scrot.png

A 1000 x 600 div:

2015-01-15--1421340008_853x572_scrot.png

The canvas is the same size as the image so an export should produce just the picture. But I haven't tested that part.

It appears as though I can't get an image to proportionally fit a container without stretching in height or width.

If the container has a different ratio than the image then either the div will have whitespace or the image will be stretched yes. I changed the .one class to a #one id in your example by the way. I pasted the code I had into your fiddle.

You could consider cropping if it really needs to fit the container perfectly. But you won't know if important parts get cut off.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.