检查图像透明度
Check image transparency
我有一个网站,人们可以在其中上传 PNG 图像并保存它。
但在他们保存之前,我需要检查图像是否包含透明度。
有没有办法检查(我更喜欢 JavaScript)图像是否不是 24 位?
<img id="imageId" src=#" onload="checkRestriction(this,'1')" alt=""/>
var isPng24Bit = false;
function checkRestriction(image, id) {
if(image.colorDepth != 24) {
PNGis24Bit = false;
} else {
PNGis24Bit = true;
}
}
您可以为此目的使用此 canvas 技术并根据您的需要自定义此代码
确保将 canvas 调整为与图像相同的大小,否则在图像未覆盖 canvas.
的情况下,某些像素将是透明的
c.width=element.width;
c.height=element.height;
示例代码和演示:
var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");
$p1=$('#results1');
$p2=$('#results2');
var img1=new Image();
img1.crossOrigin='anonymous'
img1.onload=start1;
img1.src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
function start1(){
canvas1.width=img1.width;
canvas1.height=img1.height;
ctx1.drawImage(img1,0,0);
var imgData=ctx1.getImageData(0,0,canvas1.width,canvas1.height);
var data=imgData.data;
var found1='Left canvas does not have transparency';
for(var i=0;i<data.length;i+=4){
if(data[i+3]<255){found1='Left canvas does have transparency';
break;
}
}
$p1.text(found1);
}
var img2=new Image();
img2.crossOrigin='anonymous'
img2.onload=start2;
img2.src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
function start2(){
canvas2.width=img2.width;
canvas2.height=img2.height;
ctx2.drawImage(img2,0,0);
var imgData=ctx2.getImageData(0,0,canvas2.width,canvas2.height);
var data=imgData.data;
var found2='Right canvas does not have transparency';
for(var i=0;i<data.length;i+=4){
if(data[i+3]<255){found2='Right canvas does have transparency';
break;
}
}
$p2.text(found2);
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p id=results1>Results:</p>
<p id=results2>Results:</p>
<canvas id="canvas1" width=300 height=300></canvas>
<canvas id="canvas2" width=300 height=300></canvas>
我 post 这是一种直接通过 PNG 文件 header 检查的替代方法。这样既节省了内存又不用遍历像素,无论图像大小如何,同样好的性能都是一样的。
您可以通过 HTTPRequest
或 FileReader
作为 ArrayBuffer
加载文件来完成此操作,然后只需使用 DataView
检查文件 header 结构.
PNG 文件总是以 IHDR 块开头,因此我们只需要检查它是否真的是 PNG 文件,然后假定偏移量以告知深度和类型的信息。
深度场的值可以是 1、2、4、8 和 16(1、2、4 被索引,8 = 每个通道 24 位或 8 位等)。
类型字段可以是 0(灰度)、2(true-color 或 RGB)、3(索引)、4(灰度 + alpha)和 6(RGB + alpha)。
有关 PNG 文件格式和 IHDR header 的详细信息,请参阅 this link。
loadXHR("//i.imgur.com/zpWwpEM.png", function(result) {
console.log(result); // result.buffer = original arraybuffer
});
function check(buffer, callback) {
var view = new DataView(buffer);
// is a PNG?
if (view.getUint32(0) === 0x89504E47 && view.getUint32(4) === 0x0D0A1A0A) {
// We know format field exists in the IHDR chunk. The chunk exists at
// offset 8 +8 bytes (size, name) +8 (depth) & +9 (type)
var depth = view.getUint8(8 + 8 + 8);
var type = view.getUint8(8 + 8 + 9);
callback({
depth: depth,
type: ["G", "", "RGB", "Indexed", "GA", "", "RGBA"][type],
buffer: view.buffer,
hasAlpha: type === 4 || type === 6 // grayscale + alpha or RGB + alpha
})
}
}
function loadXHR(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
if (xhr.status === 200) check(xhr.response, callback);
else consle.log("Loading error: " + xhr.statusText);
};
xhr.send();
}
相同示例,但将正在检入的图像插入 DOM:
loadXHR("//i.imgur.com/zpWwpEM.png", function(result) {
console.log(result); // result.buffer = original arraybuffer
var img = new Image();
img.onload = function() {URL.revokeObjectURL(this.src)};
img.src = URL.createObjectURL(new Blob([result.buffer]));
document.body.appendChild(img);
});
function check(buffer, callback) {
var view = new DataView(buffer);
// is a PNG?
if (view.getUint32(0) === 0x89504E47 && view.getUint32(4) === 0x0D0A1A0A) {
// We know format field exists in the IHDR chunk. The chunk exists at
// offset 8 +8 bytes (size, name) +8 (depth) & +9 (type)
var depth = view.getUint8(8 + 8 + 8);
var type = view.getUint8(8 + 8 + 9);
callback({
depth: depth,
type: ["G", "", "RGB", "Indexed", "GA", "", "RGBA"][type],
buffer: view.buffer,
hasAlpha: type === 4 || type === 6 // grayscale + alpha or RGB + alpha
})
}
}
function loadXHR(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
if (xhr.status === 200) check(xhr.response, callback);
else consle.log("Loading error: " + xhr.statusText);
};
xhr.send();
}
我有一个网站,人们可以在其中上传 PNG 图像并保存它。 但在他们保存之前,我需要检查图像是否包含透明度。 有没有办法检查(我更喜欢 JavaScript)图像是否不是 24 位?
<img id="imageId" src=#" onload="checkRestriction(this,'1')" alt=""/>
var isPng24Bit = false;
function checkRestriction(image, id) {
if(image.colorDepth != 24) {
PNGis24Bit = false;
} else {
PNGis24Bit = true;
}
}
您可以为此目的使用此 canvas 技术并根据您的需要自定义此代码
确保将 canvas 调整为与图像相同的大小,否则在图像未覆盖 canvas.
c.width=element.width;
c.height=element.height;
示例代码和演示:
var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");
$p1=$('#results1');
$p2=$('#results2');
var img1=new Image();
img1.crossOrigin='anonymous'
img1.onload=start1;
img1.src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
function start1(){
canvas1.width=img1.width;
canvas1.height=img1.height;
ctx1.drawImage(img1,0,0);
var imgData=ctx1.getImageData(0,0,canvas1.width,canvas1.height);
var data=imgData.data;
var found1='Left canvas does not have transparency';
for(var i=0;i<data.length;i+=4){
if(data[i+3]<255){found1='Left canvas does have transparency';
break;
}
}
$p1.text(found1);
}
var img2=new Image();
img2.crossOrigin='anonymous'
img2.onload=start2;
img2.src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
function start2(){
canvas2.width=img2.width;
canvas2.height=img2.height;
ctx2.drawImage(img2,0,0);
var imgData=ctx2.getImageData(0,0,canvas2.width,canvas2.height);
var data=imgData.data;
var found2='Right canvas does not have transparency';
for(var i=0;i<data.length;i+=4){
if(data[i+3]<255){found2='Right canvas does have transparency';
break;
}
}
$p2.text(found2);
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p id=results1>Results:</p>
<p id=results2>Results:</p>
<canvas id="canvas1" width=300 height=300></canvas>
<canvas id="canvas2" width=300 height=300></canvas>
我 post 这是一种直接通过 PNG 文件 header 检查的替代方法。这样既节省了内存又不用遍历像素,无论图像大小如何,同样好的性能都是一样的。
您可以通过 HTTPRequest
或 FileReader
作为 ArrayBuffer
加载文件来完成此操作,然后只需使用 DataView
检查文件 header 结构.
PNG 文件总是以 IHDR 块开头,因此我们只需要检查它是否真的是 PNG 文件,然后假定偏移量以告知深度和类型的信息。
深度场的值可以是 1、2、4、8 和 16(1、2、4 被索引,8 = 每个通道 24 位或 8 位等)。
类型字段可以是 0(灰度)、2(true-color 或 RGB)、3(索引)、4(灰度 + alpha)和 6(RGB + alpha)。
有关 PNG 文件格式和 IHDR header 的详细信息,请参阅 this link。
loadXHR("//i.imgur.com/zpWwpEM.png", function(result) {
console.log(result); // result.buffer = original arraybuffer
});
function check(buffer, callback) {
var view = new DataView(buffer);
// is a PNG?
if (view.getUint32(0) === 0x89504E47 && view.getUint32(4) === 0x0D0A1A0A) {
// We know format field exists in the IHDR chunk. The chunk exists at
// offset 8 +8 bytes (size, name) +8 (depth) & +9 (type)
var depth = view.getUint8(8 + 8 + 8);
var type = view.getUint8(8 + 8 + 9);
callback({
depth: depth,
type: ["G", "", "RGB", "Indexed", "GA", "", "RGBA"][type],
buffer: view.buffer,
hasAlpha: type === 4 || type === 6 // grayscale + alpha or RGB + alpha
})
}
}
function loadXHR(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
if (xhr.status === 200) check(xhr.response, callback);
else consle.log("Loading error: " + xhr.statusText);
};
xhr.send();
}
相同示例,但将正在检入的图像插入 DOM:
loadXHR("//i.imgur.com/zpWwpEM.png", function(result) {
console.log(result); // result.buffer = original arraybuffer
var img = new Image();
img.onload = function() {URL.revokeObjectURL(this.src)};
img.src = URL.createObjectURL(new Blob([result.buffer]));
document.body.appendChild(img);
});
function check(buffer, callback) {
var view = new DataView(buffer);
// is a PNG?
if (view.getUint32(0) === 0x89504E47 && view.getUint32(4) === 0x0D0A1A0A) {
// We know format field exists in the IHDR chunk. The chunk exists at
// offset 8 +8 bytes (size, name) +8 (depth) & +9 (type)
var depth = view.getUint8(8 + 8 + 8);
var type = view.getUint8(8 + 8 + 9);
callback({
depth: depth,
type: ["G", "", "RGB", "Indexed", "GA", "", "RGBA"][type],
buffer: view.buffer,
hasAlpha: type === 4 || type === 6 // grayscale + alpha or RGB + alpha
})
}
}
function loadXHR(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
if (xhr.status === 200) check(xhr.response, callback);
else consle.log("Loading error: " + xhr.statusText);
};
xhr.send();
}