我试图利用网络工作者将png数组合并为具有透明度的单个图像,就像Photoshop合并多个图层时一样。
我之所以这样做是因为我将组合的结果保存到indexeddb中以供离线使用,之后我在我的三个中创建了一个带有该图像的纹理。 js app。
场景是大约有400种产品,纹理 - 三维平面上的图像(产品)是3幅图像(产品标题,价格和产品图像)的混合。
我'到目前为止实现了这一点,但图像处理并不是那么好,我想知道如果我通过imageData.data
这是我到目前为止所做的,但我无法使其发挥作用。 (这是在没有网络工作者的情况下完成的,只是试图使合并工作)
var images = [];
var imageData = [];
images.push( function ( callback ) {
var mobile = new Image();
mobile.onload = function () {
console.log( "mobile loaded" );
callback( null, mobile );
};
mobile.onerror = function ( e ) {
console.log( "mobile error" );
callback( e, null );
};
mobile.src = "mobile.png";
} );
images.push( function ( callback ) {
var text = new Image();
text.onload = function () {
console.log( "text loaded" );
callback( null, text );
};
text.onerror = function ( e ) {
console.log( "text error" );
callback( e, null );
};
text.src = "text.png";
} );
async.series( images, function ( err, results ) {
if ( err ) {
console.error( err );
} else {
console.log( results );
getImageData( results );
}
} );
var getImageData = function ( images ) {
for ( var i = 0; i < images.length; i++ ) {
var canvas = document.createElement( 'canvas' );
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext( '2d' );
ctx.drawImage( images[ i ], 0, 0 );
imageData.push( ctx.getImageData( 0, 0, canvas.width, canvas.height ).data );
}
merge( imageData );
};
var merge = function ( data ) {
var merged = [];
var mixFactor = 0.5;
//var newPixel = imageMainPixel * mixFactor + imageSecPixel * ( 1 - mixFactor )
//for ( var i = 0, len = data.length; i < len; i++ ) {
for ( var j = 0, byteLen = data[ 0 ].length; j < byteLen; j += 4 ) {
var r = data[ 0 ][ j ] * mixFactor + data[ 1 ][ j ] * ( 1 - mixFactor );
var g = data[ 0 ][ j + 1 ] * mixFactor + data[ 1 ][ j + 1 ] * ( 1 - mixFactor );
var b = data[ 0 ][ j + 2 ] * mixFactor + data[ 1 ][ j + 2 ] * ( 1 - mixFactor );
var a = data[ 0 ][ j + 3 ] * mixFactor + data[ 1 ][ j + 3 ] * ( 1 - mixFactor );
merged[ j ] = r;
merged[ j + 1 ] = g;
merged[ j + 2 ] = b;
merged[ j + 4 ] = a;
}
//}
var canvas = document.getElementById( 'canvas' );
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext( '2d' );
var imageData = ctx.createImageData( 512, 512 );
imageData.data.set( merged );
ctx.putImageData( imageData, 0, 0 );
};
我目前得到的错误是:
Uncaught RangeError: Source is too large
更新
我设法通过将合并功能更改为合并图像来合并图像:
var merge = function ( data ) {
var canvas = document.getElementById( 'canvas' );
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext( '2d' );
var imageData = ctx.createImageData( 512, 512 );
var mixFactor = 0.5;
for ( var j = 0, byteLen = data[ 0 ].length; j < byteLen; j += 4 ) {
imageData.data[ j ] = data[ 0 ][ j ] * mixFactor + data[ 1 ][ j ] * ( 1 - mixFactor );
imageData.data[ j + 1 ] = data[ 0 ][ j + 1 ] * mixFactor + data[ 1 ][ j + 1 ] * ( 1 - mixFactor );
imageData.data[ j + 2 ] = data[ 0 ][ j + 2 ] * mixFactor + data[ 1 ][ j + 2 ] * ( 1 - mixFactor );
imageData.data[ j + 3 ] = data[ 0 ][ j + 3 ] * mixFactor + data[ 1 ][ j + 3 ] * ( 1 - mixFactor );
}
console.log( imageData.data.length );
ctx.putImageData( imageData, 0, 0 );
};
结果就像两张图片都有50%的不透明度。但这不是理想的结果。我希望只是将图像作为层,就像在另一个上面有多个png一样...如果顶部的那个有透明的位置,你应该能够看到它下面的图像。
也许我应该根据alpha值绘制?
答案 0 :(得分:0)
经过一番思考后,我最终检查了每个像素的alpha值,并设法完成了我想要的。我重写了这样的合并函数:
var merge = function ( data ) {
var canvas = document.getElementById( 'canvas' );
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext( '2d' );
var imageData = ctx.createImageData( 512, 512 );
var mixFactor = 0.5;
for ( var j = 0, byteLen = data[ 0 ].length; j < byteLen; j += 4 ) {
// imageData.data[ j ] = data[ 0 ][ j ] * mixFactor + data[ 1 ][ j ] * ( 1 - mixFactor );
// imageData.data[ j + 1 ] = data[ 0 ][ j + 1 ] * mixFactor + data[ 1 ][ j + 1 ] * ( 1 - mixFactor );
// imageData.data[ j + 2 ] = data[ 0 ][ j + 2 ] * mixFactor + data[ 1 ][ j + 2 ] * ( 1 - mixFactor );
// imageData.data[ j + 3 ] = data[ 0 ][ j + 3 ] * mixFactor + data[ 1 ][ j + 3 ] * ( 1 - mixFactor );
imageData.data[ j ] = ( data[ 1 ][ j + 3 ] === 0 ? data[ 0 ][ j ] : data[ 1 ][ j ] );
imageData.data[ j + 1 ] = ( data[ 1 ][ j + 3 ] === 0 ? data[ 0 ][ j + 1 ] : data[ 1 ][ j + 1 ] );
imageData.data[ j + 2 ] = ( data[ 1 ][ j + 3 ] === 0 ? data[ 0 ][ j + 2 ] : data[ 1 ][ j + 2 ] );
imageData.data[ j + 3 ] = ( data[ 1 ][ j + 3 ] === 0 ? data[ 0 ][ j + 3 ] : data[ 1 ][ j + 3 ] );
}
console.log( imageData.data.length );
ctx.putImageData( imageData, 0, 0 );
};
仍然需要一些改进,但我想现在我能够在网络工作者中合并图像:)
答案 1 :(得分:0)
修改后的代码是:
Dropzone.options.frmTarget = {
autoProcessQueue: false,
url: 'upload_files.php',
init: function () {
var myDropzone = this;
// Update selector to match your button
$("#button").click(function (e) {
e.preventDefault();
myDropzone.processQueue();
});
this.on('sending', function(file, xhr, formData) {
// Append all form inputs to the formData Dropzone will POST
var data = $('#frmTarget').serializeArray();
$.each(data, function(key, el) {
formData.append(el.name, el.value);
});
});
}
}
这是解决方案(Alpha混合)How to mix two ARGB pixels?
答案 2 :(得分:-1)
我写了a lib that handles this。不仅如此,它还处理阴影和瓷砖。