如何从base64字符串的图片数据中同步获取宽高?
How to sychronously get the width and height from a base64 string of image data?
有没有办法从 base64 编码的图像数据中同步获取图像的宽度和高度?可能是通过 header 信息。
我必须非常清楚这一点。我对异步方法不感兴趣。如果您想知道异步不起作用的原因,请继续。甚至不评论。
这是我对数据进行编码的示例代码。编码是同步的。我正在使用这个 call:
var base64ImageData:String = DisplayObjectUtils.getBase64ImageDataString(displayObject, DisplayObjectUtils.PNG, null, true);
这是我用来解码数据的代码。我在 AS3 中发现的唯一解码方法是异步的。我正在使用这个 call:
var bitmapData:BitmapData = DisplayObjectUtils.getBitmapDataFromBase64(bitmapDataString);
让我重复一遍,我正在寻找 同步 动作。它不能是异步的。
更多信息:
我在 ActionScript3 工作,它是 JavaScript 的兄弟。如果它在 JavaScript 中工作,它很可能在 AS3 中工作。但是我无法使用 dom。不向 dom 添加图像并检查值。
有用的技巧:
如果可以将宽度和高度添加到 base64 流中,然后再获取它,那也可以。
这只适用于 png 的
首先是将 base64 转换为缓冲区 (Uint8array),然后读取字节 16-20(宽度)和 20-24(高度)作为 int32 值
function getPngDimensions(base64) {
let header = base64.slice(0, 50)
let uint8 = Uint8Array.from(atob(header), c => c.charCodeAt(0))
let dataView = new DataView(uint8.buffer, 0, 28)
return {
width: dataView.getInt32(16),
height: dataView.getInt32(20)
}
}
// Just to get some random base64 images
var random = (bottom, top) => Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
var canvas = document.createElement('canvas')
canvas.width = random(10, 100)
canvas.height = random(10, 100)
console.log(`canvas width: ${canvas.width}, height: ${canvas.height}`)
var base64 = canvas.toDataURL().split(',')[1]
console.log(base64)
var dimensions = getPngDimensions(base64)
console.log(dimensions)
以下内容不起作用,但它正在尝试将 @Endless 答案转换为 AS3。到目前为止我有这个:
protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void {
var base64ImageData:String = DisplayObjectUtils.getBase64ImageDataString(this, DisplayObjectUtils.PNG, null, true);
var size:Object = getPngDimensions(base64ImageData);
}
public function getPngDimensions(base64:String):Point {
base64 = base64.split(',')[1];
trace(base64.length);
base64 = base64.replace(/\n/g, "");
trace(base64.length);
//var header:String = base64.slice(0, 52); // 50 gave error later on
var header:String = base64.slice(0, base64.length);
var base64Decoder:Base64Decoder = new Base64Decoder();
var byteArray:ByteArray;
base64Decoder.reset();
base64Decoder.decode(header);
// base64Decoder.toByteArray(); ==>
// Error: A partial block (2 of 4 bytes) was dropped. Decoded data is probably truncated!
// added the whole length (52 works as well)
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
//var width:String = byteArray.readUTFBytes(0);
//var value:ByteArray = new ByteArray();
//value.readBytes(byteArray, 0, 28);
var thing:Number = byteArray.readDouble(); // -8.091055181950927E-264
byteArray.position = 0;
var thing2:Number = byteArray.readFloat(); // -2.5073895107184266E-33
byteArray.position = 0;
var width:Number = byteArray.readFloat();
byteArray.position = 16;
var width:Number = byteArray.readFloat();
byteArray.position = 20;
var width:Number = byteArray.readFloat();
byteArray.position = 28;
var width:Number = byteArray.readFloat(); // 1.1074230549312416E-38
byteArray.position = 0;
var other:String = byteArray.readUTFBytes(byteArray.length);
// other == "PNG\r\n\n"
var point:Point = new Point();
point.x = int(width);
point.y = int(height);
return point;
}
如果我使用 ByteArray.readUTFBytes()
,结果会得到 "PNG",但没有宽度或高度。
"If I use ByteArray.readUTFBytes()
I get "PNG" as a result but no width or height."
不要将字节读取为 UTF
格式,因为那样只会提取文本字符。您需要十进制值。
readDouble
和 readFloat
太多了,他们每次操作读取 8 个字节。 PNG 格式每个宽度或高度值仅使用 4 个字节,因此只需读取(无符号)整数。
- 请记住,每个
read
操作都会自动移动字节数组的位置。例如,要知道 bytePos-1 的值,您必须 "walk"/读取它,以便最终到达 bytePos-2,或者对于 Double 类型,您将最终到达 bytePos-9。
查看您的代码的重新修复是否获得预期的宽度和高度值...
public function getPngDimensions(base64:String):Point
{
base64 = base64.split(',')[1];
trace("Base64 length A : " + base64.length);
base64 = base64.replace(/\n/g, "");
trace("Base64 length B : " + base64.length);
//var header:String = base64.slice(0, 52); // 50 gave error later on
var header:String = base64.slice(0, base64.length);
var base64Decoder:Base64Decoder = new Base64Decoder();
var byteArray:ByteArray;
base64Decoder.reset();
base64Decoder.decode(header);
// base64Decoder.toByteArray(); ==>
// Error: A partial block (2 of 4 bytes) was dropped. Decoded data is probably truncated!
// added the whole length (52 works as well)
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
//# Get Width and Height values
//# type Int is 4 bytes long so pointer auto-moves ahead by 4 bytes during Read action
byteArray.position = 16; //start position for values...
var width:int = byteArray.readUnsignedInt(); //reads 4 bytes, stops at Pos 20
var height:int = byteArray.readUnsignedInt(); //reads 4 bytes, stops at Pos 24
//# Double check (if needed)
//trace("PNG width : " + width);
//trace("PNG height : " + height);
//# Return as Point
var point:Point = new Point();
point.x = width; point.y = height;
return point;
}
有没有办法从 base64 编码的图像数据中同步获取图像的宽度和高度?可能是通过 header 信息。
我必须非常清楚这一点。我对异步方法不感兴趣。如果您想知道异步不起作用的原因,请继续。甚至不评论。
这是我对数据进行编码的示例代码。编码是同步的。我正在使用这个 call:
var base64ImageData:String = DisplayObjectUtils.getBase64ImageDataString(displayObject, DisplayObjectUtils.PNG, null, true);
这是我用来解码数据的代码。我在 AS3 中发现的唯一解码方法是异步的。我正在使用这个 call:
var bitmapData:BitmapData = DisplayObjectUtils.getBitmapDataFromBase64(bitmapDataString);
让我重复一遍,我正在寻找 同步 动作。它不能是异步的。
更多信息:
我在 ActionScript3 工作,它是 JavaScript 的兄弟。如果它在 JavaScript 中工作,它很可能在 AS3 中工作。但是我无法使用 dom。不向 dom 添加图像并检查值。
有用的技巧:
如果可以将宽度和高度添加到 base64 流中,然后再获取它,那也可以。
这只适用于 png 的 首先是将 base64 转换为缓冲区 (Uint8array),然后读取字节 16-20(宽度)和 20-24(高度)作为 int32 值
function getPngDimensions(base64) {
let header = base64.slice(0, 50)
let uint8 = Uint8Array.from(atob(header), c => c.charCodeAt(0))
let dataView = new DataView(uint8.buffer, 0, 28)
return {
width: dataView.getInt32(16),
height: dataView.getInt32(20)
}
}
// Just to get some random base64 images
var random = (bottom, top) => Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
var canvas = document.createElement('canvas')
canvas.width = random(10, 100)
canvas.height = random(10, 100)
console.log(`canvas width: ${canvas.width}, height: ${canvas.height}`)
var base64 = canvas.toDataURL().split(',')[1]
console.log(base64)
var dimensions = getPngDimensions(base64)
console.log(dimensions)
以下内容不起作用,但它正在尝试将 @Endless 答案转换为 AS3。到目前为止我有这个:
protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void {
var base64ImageData:String = DisplayObjectUtils.getBase64ImageDataString(this, DisplayObjectUtils.PNG, null, true);
var size:Object = getPngDimensions(base64ImageData);
}
public function getPngDimensions(base64:String):Point {
base64 = base64.split(',')[1];
trace(base64.length);
base64 = base64.replace(/\n/g, "");
trace(base64.length);
//var header:String = base64.slice(0, 52); // 50 gave error later on
var header:String = base64.slice(0, base64.length);
var base64Decoder:Base64Decoder = new Base64Decoder();
var byteArray:ByteArray;
base64Decoder.reset();
base64Decoder.decode(header);
// base64Decoder.toByteArray(); ==>
// Error: A partial block (2 of 4 bytes) was dropped. Decoded data is probably truncated!
// added the whole length (52 works as well)
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
//var width:String = byteArray.readUTFBytes(0);
//var value:ByteArray = new ByteArray();
//value.readBytes(byteArray, 0, 28);
var thing:Number = byteArray.readDouble(); // -8.091055181950927E-264
byteArray.position = 0;
var thing2:Number = byteArray.readFloat(); // -2.5073895107184266E-33
byteArray.position = 0;
var width:Number = byteArray.readFloat();
byteArray.position = 16;
var width:Number = byteArray.readFloat();
byteArray.position = 20;
var width:Number = byteArray.readFloat();
byteArray.position = 28;
var width:Number = byteArray.readFloat(); // 1.1074230549312416E-38
byteArray.position = 0;
var other:String = byteArray.readUTFBytes(byteArray.length);
// other == "PNG\r\n\n"
var point:Point = new Point();
point.x = int(width);
point.y = int(height);
return point;
}
如果我使用 ByteArray.readUTFBytes()
,结果会得到 "PNG",但没有宽度或高度。
"If I use
ByteArray.readUTFBytes()
I get "PNG" as a result but no width or height."
不要将字节读取为 UTF
格式,因为那样只会提取文本字符。您需要十进制值。
readDouble
和readFloat
太多了,他们每次操作读取 8 个字节。 PNG 格式每个宽度或高度值仅使用 4 个字节,因此只需读取(无符号)整数。- 请记住,每个
read
操作都会自动移动字节数组的位置。例如,要知道 bytePos-1 的值,您必须 "walk"/读取它,以便最终到达 bytePos-2,或者对于 Double 类型,您将最终到达 bytePos-9。
查看您的代码的重新修复是否获得预期的宽度和高度值...
public function getPngDimensions(base64:String):Point
{
base64 = base64.split(',')[1];
trace("Base64 length A : " + base64.length);
base64 = base64.replace(/\n/g, "");
trace("Base64 length B : " + base64.length);
//var header:String = base64.slice(0, 52); // 50 gave error later on
var header:String = base64.slice(0, base64.length);
var base64Decoder:Base64Decoder = new Base64Decoder();
var byteArray:ByteArray;
base64Decoder.reset();
base64Decoder.decode(header);
// base64Decoder.toByteArray(); ==>
// Error: A partial block (2 of 4 bytes) was dropped. Decoded data is probably truncated!
// added the whole length (52 works as well)
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
//# Get Width and Height values
//# type Int is 4 bytes long so pointer auto-moves ahead by 4 bytes during Read action
byteArray.position = 16; //start position for values...
var width:int = byteArray.readUnsignedInt(); //reads 4 bytes, stops at Pos 20
var height:int = byteArray.readUnsignedInt(); //reads 4 bytes, stops at Pos 24
//# Double check (if needed)
//trace("PNG width : " + width);
//trace("PNG height : " + height);
//# Return as Point
var point:Point = new Point();
point.x = width; point.y = height;
return point;
}