Javascript 在javascript画布上混合两个图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3648312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:34:59  来源:igfitidea点击:

blend two images on a javascript canvas

javascriptgraphicshtmlcanvas

提问by davivid

How do you blend two arrays of pixel data to create one image? with the option of using different blending modes?

你如何混合两个像素数据数组来创建一个图像?可以选择使用不同的混合模式?

回答by pepkin88

Pixastic is a special framework for advanced use of canvas, here are blending examples: http://www.pixastic.com/lib/docs/actions/blend/

Pixastic 是一个特殊的画布高级使用框架,这里有混合示例:http://www.pixastic.com/lib/docs/actions/blend/

If you would like do this alone, you can extract pixel data from 2 images, blend it with a mathematical equation, and put into a canvas. Here is information how to get and put pixel data from/to canvas: http://ajaxian.com/archives/canvas-image-data-optimization-tip

如果您想单独执行此操作,您可以从 2 张图像中提取像素数据,将其与数学方程混合,然后放入画布中。以下是如何从/到画布获取和放置像素数据的信息:http: //ajaxian.com/archives/canvas-image-data-optimization-tip



Update:Simple example with alpha blending of 2 images in proportion 50-50. (Images borrowed from http://www.pixastic.com/sample/Butterfly.jpgand http://www.pixastic.com/sample/Flower.jpg)

更新:以 50-50 的比例混合 2 张图像的简单示例。(图片借自http://www.pixastic.com/sample/Butterfly.jpghttp://www.pixastic.com/sample/Flower.jpg

<img src="Butterfly.jpg" id="img1">
<img src="Flower.jpg" id="img2">
<p>Blended image<br><canvas id="canvas"></canvas></p>
<script>
window.onload = function () {
    var img1 = document.getElementById('img1');
    var img2 = document.getElementById('img2');
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    var width = img1.width;
    var height = img1.height;
    canvas.width = width;
    canvas.height = height;

    var pixels = 4 * width * height;
    context.drawImage(img1, 0, 0);
    var image1 = context.getImageData(0, 0, width, height);
    var imageData1 = image1.data;
    context.drawImage(img2, 0, 0);
    var image2 = context.getImageData(0, 0, width, height);
    var imageData2 = image2.data;
    while (pixels--) {
        imageData1[pixels] = imageData1[pixels] * 0.5 + imageData2[pixels] * 0.5;
    }
    image1.data = imageData1;
    context.putImageData(image1, 0, 0);
};
</script>

回答by Phrogz

I have created a separate, lightweight, open-source library for perform Photoshop-style blend modes from one HTML Canvas context to another: context-blender. Here's the sample usage:

我创建了一个单独的、轻量级的、开源的库,用于从一个 HTML Canvas 上下文到另一个执行 Photoshop 风格的混合模式:context-blender。这是示例用法:

// Might be an 'offscreen' canvas
var over  = someCanvas.getContext('2d');
var under = anotherCanvas.getContext('2d');

over.blendOnto( under, 'screen', {destX:30,destY:15} );

See the READMEfor more information.

有关更多信息,请参阅自述文件

回答by Jay

I am tasked with recreating thisjava applet using JavaScript (must be tablet friendly, and work in all modern browsers > IE8). I am creating images using: var image1 = new Image();and then setting source: img.src = "some path";

我的任务是使用 JavaScript重新创建这个Java 小程序(必须对平板电脑友好,并且可以在所有现代浏览器 > IE8 中工作)。我正在使用以下方法创建图像:var image1 = new Image();然后设置源:img.src = "some path";

So, from pepkin88I see that the following function will blend two images by combining their pixel array data, overriding previous data from the first image with the new blended data, and finally putting the new data on the canvas resulting in a blended image:

因此,从pepkin88我看到以下函数将通过组合两个图像的像素阵列数据来混合两个图像,用新的混合数据覆盖来自第一个图像的先前数据,最后将新数据放在画布上产生混合图像:

window.onload = function () {
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = img1.width;
var height = img1.height;
canvas.width = width;
canvas.height = height;

var pixels = 4 * width * height;
context.drawImage(img1, 0, 0);
var image1 = context.getImageData(0, 0, width, height);
var imageData1 = image1.data;
context.drawImage(img2, 0, 0);
var image2 = context.getImageData(0, 0, width, height);
var imageData2 = image2.data;
while (pixels--) {
    imageData1[pixels] = imageData1[pixels] * 0.5 + imageData2[pixels] * 0.5;
}
image1.data = imageData1;
context.putImageData(image1, 0, 0); };
window.onload = function () {
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = img1.width;
var height = img1.height;
canvas.width = width;
canvas.height = height;

var pixels = 4 * width * height;
context.drawImage(img1, 0, 0);
var image1 = context.getImageData(0, 0, width, height);
var imageData1 = image1.data;
context.drawImage(img2, 0, 0);
var image2 = context.getImageData(0, 0, width, height);
var imageData2 = image2.data;
while (pixels--) {
    imageData1[pixels] = imageData1[pixels] * 0.5 + imageData2[pixels] * 0.5;
}
image1.data = imageData1;
context.putImageData(image1, 0, 0); };

HOWEVER, if you viewed the java applet that I'm responsible for recreating, you see that blending happens in real-time continuously as you drag the image around with the pointer the images are constantly blending based on their overlapped regions..

但是,如果您查看了我负责重新创建的 Java 小程序,您会看到当您使用指针拖动图像时,混合是实时连续发生的,图像根据重叠区域不断混合。

SO, I'm looking to modify the code to account for this, and I continually have the x, y, positions of images drawn (based on top left corner), and the w, h of all images stays static:

所以,我希望修改代码来解决这个问题,并且我不断地绘制图像的 x、y 位置(基于左上角),并且所有图像的 w、h 保持静态:

the following snippets don't include everything I'm doing, just what I sense is important for you to know

以下片段不包括我正在做的所有事情,只是我觉得对你很重要

//Rectangle Class from Java converted to JS
function Rectangle(x, y, width, height, src) {
        this.x   = x; 
        this.y   = y; 
        this.w   = width;
        this.h   = height;
        this.img = new Image();
        this.img.src = src;
    }

//Stores instance in rect array
rect[0] = new Rectangle(1, (height - 111)/2, 150, 105, "images/mMain.png");

//Draw method that's called
Rectangle.prototype.draw = function(ctx) {
        //this.checkBound();
        ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
        prepareMix(this.img, this.x, this.y, this.w, this.h);
    }

So, I'm working on a prepareMix function that receives image info and uses it to get and store image data:

因此,我正在研究接收图像信息并使用它来获取和存储图像数据的 prepareMix 函数:

 function prepareMix(src, x, y, w, h) {

        pixels = 4 * w * h;
        var image = mtx.getImageData(x, y, w, h);
        var imgData = image.data; 
    }

Made a list of what to do:

列出要做的事情:

  1. Sense the overlapping
  2. Get and Store the overlapping image data
  3. Mix the overlapping region data arrays
  4. Replace the overlapping image data with the blended data
  5. Put the new data on the canvas
  1. 感知重叠
  2. 获取和存储重叠图像数据
  3. 混合重叠区域数据数组
  4. 用混合数据替换重叠图像数据
  5. 将新数据放在画布上

1. Sense the Overlapping:

1. 感知重叠:

Plan:Store image positions and compare positions data to know whether or not overlapping is occurring. IF overlapping is TRUE, which two images is it true for? Distinguish these images that're overlapping from other images so that methods can be called on them.

计划:存储图像位置并比较位置数据以了解是否发生重叠。如果重叠为真,哪两个图像是真的?区分这些与其他图像重叠的图像,以便可以对它们调用方法。

js, css, html, and images in zip here BOX

js、css、html 和 zip 中的图像在这里BOX