Han*_*Han 3 google-chrome canvas html5-canvas
我有代码从视频中绘制图像.这是代码
<script type="text/javascript">
function capture() {
var video = document.getElementById("videoId");
var canvas = capture(video, 1);
var dataURL = canvas.toDataURL("image/bmp", 1.0);
console.log("dataurl: "+dataURL);
}
</script>
<body>
<input type="button" value="Capture" onClick="capture()"/>
<video id="videoId" width="640" height="480"/>
</body>
Run Code Online (Sandbox Code Playgroud)
在控制台上,dataurl显示为"data:image/png; base64,..."
题?
为什么dataurl是以png格式生成的?
注意:这发生在chrome浏览器[41.0.2272.89]中.在firefox中,url是以bmp格式生成的.
小智 6
并非所有浏览器都支持BMP.没有要求支持除PNG之外的其他格式(我的重点):
用户代理必须支持PNG("image/png").用户代理可以支持其他类型.
任何无法识别的格式都将保存为默认PNG.
第一个参数(如果提供)控制要返回的图像的类型(例如PNG或JPEG).默认为image/png; 如果不支持给定类型,也会使用该类型.
要检查是否支持格式,请检查返回数据的第一部分-uri:
var wantType = "image/bmp";
var dataUri = canvas.toDataURL(wantType);
if (dataUri.indexOf(wantType) < 0) { // or use substr etc. data: + mime
// Format NOT supported - provide workaround/inform user
// See update below for workaround (or replacement)
}
Run Code Online (Sandbox Code Playgroud)
要保存为BMP,您必须从画布中提取像素数据,格式化文件头,以正确的格式附加数据,创建Blob并通过objectURL将其提供给用户.
用法:
var bmpDataUri = CanvasToBMP.toDataURL(canvas); // returns an data-URI
Run Code Online (Sandbox Code Playgroud)
还可以选择将BMP图像作为原始图像ArrayBuffer:
var bmpBuffer = CanvasToBMP.toArrayBuffer(canvas);
Run Code Online (Sandbox Code Playgroud)
并且Blob:
var bmpBlob = CanvasToBMP.toBlob(canvas);
var url = URL.createObjectURL(bmpBlob); // example objectURL
Run Code Online (Sandbox Code Playgroud)
Blobs当然可以使用createObjectURL()它可以用作图像源以及下载目标,并且往往比使用数据URI更快,因为它们不需要对Base-64进行编码/解码.
它写入支持alpha的32位BMP文件(Firefox目前忽略BMP文件中的alpha通道).
无论如何,这里是 -
/*! canvas-to-bmp version 1.0 ALPHA
(c) 2015 Ken "Epistemex" Fyrstenberg
MIT License (this header required)
*/
var CanvasToBMP = {
/**
* Convert a canvas element to ArrayBuffer containing a BMP file
* with support for 32-bit (alpha).
*
* Note that CORS requirement must be fulfilled.
*
* @param {HTMLCanvasElement} canvas - the canvas element to convert
* @return {ArrayBuffer}
*/
toArrayBuffer: function(canvas) {
var w = canvas.width,
h = canvas.height,
w4 = w * 4,
idata = canvas.getContext("2d").getImageData(0, 0, w, h),
data32 = new Uint32Array(idata.data.buffer), // 32-bit representation of canvas
stride = Math.floor((32 * w + 31) / 32) * 4, // row length incl. padding
pixelArraySize = stride * h, // total bitmap size
fileLength = 122 + pixelArraySize, // header size is known + bitmap
file = new ArrayBuffer(fileLength), // raw byte buffer (returned)
view = new DataView(file), // handle endian, reg. width etc.
pos = 0, x, y = 0, p, s = 0, a, v;
// write file header
setU16(0x4d42); // BM
setU32(fileLength); // total length
pos += 4; // skip unused fields
setU32(0x7a); // offset to pixels
// DIB header
setU32(108); // header size
setU32(w);
setU32(-h >>> 0); // negative = top-to-bottom
setU16(1); // 1 plane
setU16(32); // 32-bits (RGBA)
setU32(3); // no compression (BI_BITFIELDS, 3)
setU32(pixelArraySize); // bitmap size incl. padding (stride x height)
setU32(2835); // pixels/meter h (~72 DPI x 39.3701 inch/m)
setU32(2835); // pixels/meter v
pos += 8; // skip color/important colors
setU32(0xff0000); // red channel mask
setU32(0xff00); // green channel mask
setU32(0xff); // blue channel mask
setU32(0xff000000); // alpha channel mask
setU32(0x57696e20); // " win" color space
// bitmap data, change order of ABGR to BGRA
while (y < h) {
p = 0x7a + y * stride; // offset + stride x height
x = 0;
while (x < w4) {
v = data32[s++]; // get ABGR
a = v >>> 24; // alpha channel
view.setUint32(p + x, (v << 8) | a); // set BGRA
x += 4;
}
y++
}
return file;
// helper method to move current buffer position
function setU16(data) {view.setUint16(pos, data, true); pos += 2}
function setU32(data) {view.setUint32(pos, data, true); pos += 4}
},
/**
* Converts a canvas to BMP file, returns a Blob representing the
* file. This can be used with URL.createObjectURL().
* Note that CORS requirement must be fulfilled.
*
* @param {HTMLCanvasElement} canvas - the canvas element to convert
* @return {Blob}
*/
toBlob: function(canvas) {
return new Blob([this.toArrayBuffer(canvas)], {
type: "image/bmp"
});
},
/**
* Converts the canvas to a data-URI representing a BMP file.
* Note that CORS requirement must be fulfilled.
*
* @param canvas
* @return {string}
*/
toDataURL: function(canvas) {
var buffer = new Uint8Array(this.toArrayBuffer(canvas)),
bs = "", i = 0, l = buffer.length;
while (i < l) bs += String.fromCharCode(buffer[i++]);
return "data:image/bmp;base64," + btoa(bs);
}
};
// -------- DEMO CODE -------------
var canvas = document.querySelector("canvas"),
w = canvas.width,
h = canvas.height,
ctx = canvas.getContext("2d"),
gr = ctx.createLinearGradient(0, 0, w, h),
img = new Image();
gr.addColorStop(0, "hsl(" + (Math.random() * 360) + ", 90%, 70%)");
gr.addColorStop(1, "hsl(" + (Math.random() * 360) + ", 100%, 30%)");
ctx.fillStyle = gr;
ctx.fillRect(0, 0, w, h);
// append image from the data-uri returned by the CanvasToBMP code below:
img.src = CanvasToBMP.toDataURL(canvas);
document.body.appendChild(img);Run Code Online (Sandbox Code Playgroud)
<h2>Canvas left, BMP from canvas as image right</h2>
<canvas width="299" height="200"></canvas>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3921 次 |
| 最近记录: |