Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5画布透明度与PNG_Javascript_Html_Canvas_Transparency - Fatal编程技术网

Javascript HTML5画布透明度与PNG

Javascript HTML5画布透明度与PNG,javascript,html,canvas,transparency,Javascript,Html,Canvas,Transparency,我试图对从画布检索到的一些图像数据应用透明度。很简单,对吧?只需为每四个数据点设置一个适当的值。。。只是,它似乎只适用于没有预先存在的alpa值的像素 //create 2 canvases var canvas = document.createElement("canvas"); document.body.appendChild(canvas); var ctx = canvas.getContext("2d"); canvas.id = "tempCanvas"; var canvas2

我试图对从
画布
检索到的一些
图像数据
应用透明度。很简单,对吧?只需为每四个数据点设置一个适当的值。。。只是,它似乎只适用于没有预先存在的alpa值的像素

//create 2 canvases
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
canvas.id = "tempCanvas";
var canvas2 = document.createElement("canvas");
document.body.appendChild(canvas2);
var ctx2 = canvas2.getContext("2d");
canvas2.id = "tempCanvas2";

//draw the png in the first canvas
var testimg = document.getElementById("testimg");
ctx.drawImage(testimg, 0, 0, 200, 200);

//helper function to opacity to the pixels
opacity = function(pixels, value){
    var d = pixels.data;
    for(var i=0;i<d.length;i+=4){
        d[i+3] = value*255; //scale by 255
        if(d[i+3] > 255) d[i+3] = 255; //clamp
    }
    return pixels;
}

//make the first canvas' image data opaque
var data = ctx.getImageData(0,0,200,200);
data = opacity(data, 0.5);
//draw to second canvas
ctx2.fillStyle="#900";
ctx2.fillRect(0,0,200,200);

//should get a jsfiddle logo overlayed on red background
//instead, get yucky grey background
ctx2.putImageData(data, 0, 0);
//创建2张画布
var canvas=document.createElement(“canvas”);
document.body.appendChild(画布);
var ctx=canvas.getContext(“2d”);
canvas.id=“tempCanvas”;
var canvas2=document.createElement(“canvas”);
文件.正文.附件(canvas2);
var ctx2=canvas2.getContext(“2d”);
canvas2.id=“tempCanvas2”;
//在第一个画布中绘制png
var testimg=document.getElementById(“testimg”);
ctx.drawImage(testimg,0,0,200,200);
//帮助器函数用于不透明度到像素
不透明度=函数(像素、值){
var d=像素数据;
对于(var i=0;i 255)d[i+3]=255;//钳位
}
返回像素;
}
//使第一个画布的图像数据不透明
var data=ctx.getImageData(0,02000);
数据=不透明度(数据,0.5);
//绘制到第二个画布
ctx2.fillStyle=“#900”;
ctx2.fillRect(0,0200200);
//应该在红色背景上覆盖一个JSFIDLE徽标
//取而代之的是,使用令人恶心的灰色背景
ctx2.putImageData(数据,0,0);
(由于同源政策,复制起来有点困难,但这里有一个使用png JSFIDLE徽标的FIDLE:)

为什么这种不透明算法不适用于JSFIDLE徽标(以及我正在测试的其他透明PNG)


编辑:FF42 Ubuntu,如果有区别的话。

您遇到了big-endian/little-endian问题:在当今大多数计算机/设备上,endian是little-endian,这意味着对于32位值,字节顺序是3-2-1-0

因此,不透明度,即第4个字节(索引3),将在
pixelIndex*4+0
..=<代码>像素索引*4

只需在代码中将不透明度函数更改为:

opacity = function(pixels, value){
    var d = pixels.data;
    for(var i=0;i<d.length;i+=4){
        d[i] = value*255; //scale by 255
        if(d[i] > 255) d[i] = 255; //clamp
    }
    return pixels;
}
顺便说一下,你的函数可以简化为

opacity = function(pixels, value){
    value = Math.floor(value * 255);
    if (value>255) value = 255;
    var d = pixels.data;
    for(var i=0;i<d.length;i+=4){
        d[i] = value;
    }
    return pixels;
}
opacity=函数(像素,值){
值=数学地板(值*255);
如果(值>255)值=255;
var d=像素数据;

对于(var i=0;iMind blow)。但是,为什么在更新的小提琴中背景不是红色的呢?
opacity = function(pixels, value){
    value = Math.floor(value * 255);
    if (value>255) value = 255;
    var d = pixels.data;
    for(var i=0;i<d.length;i+=4){
        d[i] = value;
    }
    return pixels;
}