如何创建一个图像生成器来组合多个图像?

问题描述 投票:0回答:3

我正在使用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度,但不会定位到右角。第二张图像也应位于第一张图像旁边。

如何并排进行每个图像的旋转和定位?

工作小提琴:https://jsfiddle.net/8ww1x4eq/2/

javascript jquery html5 canvas
3个回答
1
投票

看看更新的jsFiddle,这是你想要的吗?

看看这里关于image rotation

Updated jsFiddle,绘制多个图像。

注意:

  1. 保存脚本只是一种懒惰的方法,以确保在保存merged_image之前我已经加载了外部脚本...
  2. 示例脚本中没有同步,注意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!


0
投票

您可以使用toDataURL。但通过这种方式,用户必须执行类似将图像另存为...

var img = canvas.toDataURL("image/png");

然后设置为例如img结果src:

$("#result").attr("src",img);

0
投票

Canvas已经是一个Image。

canvasimg是可以互换的,所以没有必要添加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);
}
© www.soinside.com 2019 - 2024. All rights reserved.