我正在使用HTML5 canvas和jQuery / JS开发图像生成器。我想要完成的是以下内容。
用户可以将2个或最多3个图像(类型应为png或jpg)上传到画布。生成的图像应始终为1080x1920。如果哈特仅上传2张图片,则图片为1080x960。如果上传了3张图像,则每张图像的尺寸应为1080x640。
上传2或3张图像后,用户可以单击下载按钮获取合并后的图像,格式为1080x1920px。
它应该使用html canvas来完成这项工作。
我想出了这个:
HTML:
<canvas id="canvas">
Sorry, canvas not supported
</canvas><!-- /canvas.offers -->
<input id="fileInput" type="file" />
<a href="#" class="generate">Generate</a>
jQuery的:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
var img1 = loadImage('http://www.shsu.edu/dotAsset/0e829093-971c-4037-9c1b-864a7be1dbe8.png', main);
var img2 = loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Ikea_logo.svg/266px-Ikea_logo.svg.png', main);
var minImages = 2;
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if(imagesLoaded >= minImages) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawImage(img1, 0, 0);
// ctx.translate(canvas.height/2,canvas.width/2); // move to the center of the canvas
// ctx.rotate(270*Math.PI/180); // rotate the canvas to the specified degrees
// ctx.drawImage(img2,0,canvas.height/2);
ctx.translate(-canvas.height/2,canvas.width/2); // move to the center of the canvas
ctx.rotate(90*Math.PI/180); // rotate the canvas to the specified degrees
ctx.drawImage(img2,-img2.width/2,-img2.width/2);
ctx.restore(); // restore the unrotated context
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
console.log(img);
return img;
}
上面的代码将创建画布并将两个图像(现在在JS中硬编码)放置到创建的画布上。它将旋转90度,但不会定位到右角。第二张图像也应位于第一张图像旁边。
如何并排进行每个图像的旋转和定位?
看看更新的jsFiddle,这是你想要的吗?
看看这里关于image rotation
Updated jsFiddle,绘制多个图像。
注意:
addToCanvas
在图像加载事件上被调用,这里可能存在竞争条件(但我怀疑它,因为图像被加载到客户端的内存)function addToCanvas(img) {
// resize canvas to fit the image
// height should be the max width of the images added, since we rotate -90 degree
// width is just a sum of all images' height
canvas.height = max(lastHeight, img.width);
canvas.width = lastWidth + img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (lastImage) {
ctx.drawImage(lastImage, 0, canvas.height - lastImage.height);
}
ctx.rotate(270 * Math.PI / 180); // rotate the canvas to the specified degrees
ctx.drawImage(img, -canvas.height, lastWidth);
lastImage = new Image();
lastImage.src = canvas.toDataURL();
lastWidth += img.height;
lastHeight = canvas.height;
imagesLoaded += 1;
}
PS:我已经添加了一些脚本来下载合并的图像,但它会失败。错误消息是:“未捕获的SecurityError:无法在'HTMLCanvasElement'上执行'toDataURL':可能无法导出受污染的画布。”
我已经快速完成了谷歌搜索,它似乎与跨源资源有关。我认为它不会是FileReader的问题。 我没有时间测试,所以请测试一下(请告诉我:) 它适用于FileReader!
您可以使用toDataURL。但通过这种方式,用户必须执行类似将图像另存为...
var img = canvas.toDataURL("image/png");
然后设置为例如img结果src:
$("#result").attr("src",img);
Canvas已经是一个Image。
canvas
和img
是可以互换的,所以没有必要添加canvas.toDataURL
的风险步骤,这可能会失败,具体取决于图像源域。只需将画布看作是img并将其放入DOM中即可。转换为jpg不会节省空间(实际上是资源饥饿的操作),因为img需要在显示之前进行解码。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
document.body.appendChild(canvas); // add to the end of the document
// or add it to a containing element
var container = document.getElementById("containerID"); // or use JQuery
if(container !== null){
container.appendChild(canvas);
}