繁体   English   中英

如何从base64图像数据字符串中同步获取宽度和高度?

[英]How to sychronously get the width and height from a base64 string of image data?

有没有办法从base64编码的图像数据中同步获取图像的宽度和高度? 可能是标题信息。

我必须说得很清楚。 我对异步方法不感兴趣。 如果您想知道异步不起作用的原因,请继续。 甚至不发表评论。

这是我的示例代码来编码我的数据。 编码是同步的。 我正在使用这个电话

var base64ImageData:String = DisplayObjectUtils.getBase64ImageDataString(displayObject, DisplayObjectUtils.PNG, null, true);

这是我的代码来解码我的数据。 我在AS3中发现的唯一解码方法是异步的。 我正在使用这个电话

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”,但没有宽度或高度。

“如果我使用ByteArray.readUTFBytes() ,结果是“ PNG”,但没有宽度或高度。”

不要将字节读取为UTF格式,因为这只会提取文本字符。 您需要十进制值。

  • readDoublereadFloat太多,每个动作读取8个字节。 PNG格式每个宽度或高度值仅使用4个字节,因此只需读取(无符号)整数。
  • 请记住,每个read动作都会自动移动byteArray的位置。 例如,要知道bytePos-1的值,您必须“遍历” /读取它的值,以便最终到达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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM