Resizing image with Canvas and JavaScript

2

How to reduce the size of an image with JavaScript ? I'm using canvas to resize, reduce size in proportion and converting to jpeg .

The problem occurs when I try to save the image, since I can not download it converted to jpeg .

Follow the code in JsFidle .

link

Note: console.log() returns that type is jpeg , but when you right-click to try to save it, it is png .

Any suggestions on how to solve the problem?

    
asked by anonymous 12.02.2015 / 16:51

2 answers

0

According to this documentation there is a kind of "flaw", or rather, this is the canvas resource in getting jpeg:

link

There is already a topic about this:

link

According to these two searches your solution would create a kind of link or force download when clicking on the image. This is very simple. An example link:

/**
 *    Ken Fyrstenberg Nilsen
 *    Abidas Software
 */
var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d');

/**
 * Functions for demo
 */
function doCanvas() {

    //some background
    var s = canvas.width / 5;
    var i = 0;
    var r = Math.random;


    var txt = 'Normal text';
    var itxt = 'Inversed text';

    ctx.fillStyle = '#fff';
    
    ctx.textBaseline = 'top';
    ctx.font = '80px impact'
    ctx.fillText(txt, 30, 20);

    ctx.fillInversedText(itxt, 30, 100);
    
    requestAnimationFrame(doCanvas);
}

/**
 * Canvas extension: fillInversedText
 * By Ken Fyrstenberg Nilsen 2013. Beta 1.
*/
CanvasRenderingContext2D.prototype.fillInversedText = function (txt, x, y) {

    //measure
    var tw = this.measureText(txt).width;
    var th = parseInt(ctx.font, '10');
    th = (th === 0) ? 16 : th;

    //setupp off-screen canvas
    var co = document.createElement('canvas');
    co.width = tw;
    co.height = th;

    //fill text
    var octx = co.getContext('2d');
    octx.font = this.font;
    octx.textBaseline = 'top';
    octx.fillText(txt, 0, 0);

    //get pixel buffers
    var ddata = this.getImageData(x, y, tw, th);
    var sdata = octx.getImageData(0, 0, tw, th);

    var dd = ddata.data;
    var ds = sdata.data;
    var len = ds.length;
    
    //invert
    for (var i = 0; i < len; i += 4) {
        if (ds[i + 3] > 0) {
            dd[i] = (255 - dd[i]);
            dd[i + 1] = (255 - dd[i + 1]);
            dd[i + 2] = (255 - dd[i + 2]);
        }
    }

    //result at x/y
    this.putImageData(ddata, x, y);
}

/**
 * Init generals
 */
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);

function download() {
    var dt = canvas.toDataURL();
    this.href = dt; //this may not work in the future..
}
document.getElementById('download').addEventListener('click', download, false);

/**
 * Monkey patches
 */
window.requestAnimationFrame = (function () {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
        window.setTimeout(callback, 1000 / 60);
    };
})();

window.cancelAnimationFrame = (function () {
    return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function (timPtr) {
        window.clearTimeout(timPtr);
    };
})();

/**
 * START
 */
doCanvas();
	body {
	    background-color:#555657;
	    padding:0;
	    margin:0;
	    overflow:hidden;
	    font-family:sans-serif;
	    -webkit-user-select: none;
	    -khtml-user-select: none;
	    -moz-user-select: none;
	    -ms-user-select: none;
	    user-select: none;
	}
	canvas {
	    border:1px solid #000;
	    float:left;
	    clear:both;
	}
	#download {
	    clear:both;
	    float:left;
	    cursor:pointer;
	    color:#ccc;
	    padding:3px;
	}
	#download:hover {
	    color:#fff;
	}
	/*
	div, input {
	    font-size:16px;
	    font-family:sans-serif;
	    border:1px solid #000;
	    border-radius: 5px;
	    float:left;
	    padding:5px;
	    width:50px;
	    margin:1px 1px;
	    background-color:#bbb;
	}
	input[type='text'] {
	    font-size:16px;
	    font-weight:bold;
	    width:70px;
	    text-align:center;
	    background-color:#fff;
	    padding-bottom:4px;
	}
	input[type='button'] {
	    font-size:16px;
	    font-weight:bold;
	    width:110px;
	    text-align:center;
	    background-color:#333;
	    color:#eee;
	    padding-bottom:4px;
	}
	input[type='button']:hover {
	    background-color:#fff463;
	    color:#000;
	}
	input[type='range'] {
	    width:100px;
	    margin:0 0 0 10px;
	}
*/
	
<canvas width="500" height="210" id="canvas">Sorry, no canvas available</canvas>
<a id="download" download="AbdiasCanvasDemo.png">Download as image</a>
    
12.02.2015 / 17:45
0

There is an error in your code, how do you get the image on the canvas without first drawing it?

var img2 = new Image();
img2.src = canvas.toDataURL("image/jpeg", 1.0);
//Exibe (desenha) a imagem na tela
ctx.drawImage(img, 0, 0, width, height);

The right thing would be:

//Exibe (desenha) a imagem na tela
ctx.drawImage(img, 0, 0, width, height);
var img2 = new Image();
img2.src = canvas.toDataURL("image/jpeg", 1.0);

With this you could already get the expected result, why do you even want to display your jpg image on the canvas? if so, the canvas would turn it into png again then the correct one would be to show it in the gift:

document.body.appendChild(img2);

This would mean that if the user wanted to save the image, it would already be in jpg.

Test your edited code here:

var img = document.getElementById("preview");

var canvas = document.getElementById("canvas");

var ctx = canvas.getContext("2d");

var MAX_WIDTH = 800;
var MAX_HEIGHT = 800;

var width = img.width;
var height = img.height;

if (width > height) {
  if (width > MAX_WIDTH) {
    height *= MAX_WIDTH / width;
    width = MAX_WIDTH;
  }
} else {
  if (height > MAX_HEIGHT) {
    width *= MAX_HEIGHT / height;
    height = MAX_HEIGHT;
  }
}

canvas.width = width;
canvas.height = height;

//Exibe (desenha) a imagem na tela
ctx.drawImage(img, 0, 0, width, height);
var img2 = new Image();
img2.src = canvas.toDataURL("image/jpeg", 1.0);

document.body.appendChild(img2);

console.log(img2);
<img crossOrigin="anonymous" id="preview" style="display:none;" src="https://lh3.googleusercontent.com/-zXZsjsGeYX0/UiuAEl31SDI/AAAAAAAABYI/g77Sb8-lzbY/w1109-h633-no/15-02-2013_internet.jpg"><canvasid="canvas" style="background-size:contain;display:none;"></canvas>
    
12.02.2015 / 18:10