微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将BitmapData从Flash转换为canvas HTML?

如何解决如何将BitmapData从Flash转换为canvas HTML?

我陷入了一个相当严重的问题。我将Flash重新编写为JS,并遇到了SOAP返回的数据处理问题。这是关于我以字符串形式获取的图像,并转换为Flash中使用的BitmapData。 我尝试了许多不同的方法,但充其量只能在画布上获得带噪点的绿色图像。以下是您可能会发现有用的所有代码

来自Flash的代码

        private function encode(bitmap:Bitmap):ByteArray{
            var encoder:JPGEncoder = new JPGEncoder(QUALITY);
            return encoder.encode(bitmap.bitmapData);
        }

        public function decodeBytes(bm:Bitmap):void{
            _bitmap = bm;
            _bytesData = encode(_bitmap);
            var imgConventer:ArrayDataConventer = new ArrayDataConventer();
            imgConventer.addEventListener(ImageConvertCompleteEvent.IMAGE_CONVERT_COMPLETE,convertCompleteHandler);
            imgConventer.decByteArrToHexStr(bytesData);
        }   

decByteArrToHexStr返回字符串,其中两个十六进制字符表示字节。并将此字符串推送到SOAP并在我想要获取它时将其返回。这就是Flash的一部分。

现在,我希望将此字符串转换为可以放入画布的图像数据。

我有字符串转换为Uint8Array的方法

  public hexStrToDecByteArr(str: string): Uint8Array {
    const byteArr: Uint8Array = new Uint8Array(str.length / 2);

    for (let i: number = 0; i < str.length; i = i + 2) {
      const n: number = parseInt('0x' + str.substr(i,2),0);

      if (!isNaN(n)) {
        byteArr[i] = n;
      }
    }

    return data;
  }

然后在响应处理程序中,我有这样的东西:

const decodes: ArrayDataConverter = new ArrayDataConverter();
        const data = decodes.hexStrToDecByteArr(downloadedImage.sData);
        const encoder: any = new JPGEncoder(100);
        const encoded = encoder.encode({width: 400,height: 300,data});

        const context = this.canvas.nativeElement.getContext('2d');
        context.clearRect(0,400,300);

        const image = new Image();
        image.onload = () => {
          context.drawImage(image,0);
        };
        image.src = encoded;

因此,downloadedImage.sData包含十六进制字符串。 JPGEncoder是我找到的软件包,它是重写为JS(https://www.npmjs.com/package/@koba04/jpeg-encoder)的JPGEncoder Flash版本。

正如我之前提到的,我正在画布上获得一些带有噪点的绿色图像。

谢谢。

解决方法

您似乎正在使用JPEG压缩来压缩实际的像素颜色(原始位图数据),然后尝试将相同的JPEG数据加载到HTML5画布中?

这种方法行不通,因为Canvas期望像素颜色值不是JPEG压缩算法。

可能的解决方案1 ​​:在画布中使用AS3像素值...

在您的AS3代码中,不要编码为JPEG,而只需将像素值写为十六进制字符串(来自Array)即可。

public function decodeBytes(bm:Bitmap):void
{
    //# get pixel values into an array named: _bytesData
    bm.bitmapData.copyPixelsToByteArray( bm.bitmapData.rect,_bytesData );
    
    var imgConventer:ArrayDataConventer = new ArrayDataConventer();
    imgConventer.addEventListener(ImageConvertCompleteEvent.IMAGE_CONVERT_COMPLETE,convertCompleteHandler);
    imgConventer.decByteArrToHexStr( _bytesData );
}

然后在TypeScript(或JavaScript)端,只需将接收到的数据读取到数组/缓冲区中即可。

要在(HTML5)画布中显示图像,您必须使用for循环来读取数组

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var imgData = ctx.createImageData( canvas.width,canvas.height );

//# notice the order is:
//# JS imagedata = R-G-B-A
//# AS3 bitmap   = A-R-G-B

for (var i=0; i < imgData.data.length; i += 4)
{
    imgData.data[i + 0] = downloadedImage.sData[i + 1]; //put RED
    imgData.data[i + 1] = downloadedImage.sData[i + 2]; //put GREEN
    imgData.data[i + 2] = downloadedImage.sData[i + 3]; //put BLUE
    imgData.data[i + 3] = downloadedImage.sData[i + 0]; //put ALPHA
}

//# Update canvas with the image data
ctx.putImageData(imgData,0);

这应该在您的网页上的画布(其中id myCanvas中)中显示您的图像。

可能的解决方案2 :在数组中使用JPEG数据...

由于上述发送原始位图数据的方法可能意味着您正在发送一个大文件,因此您仍然可以尝试使用JPEG压缩,并且这种方式意味着您可以将JPEG数组直接加载到<Image>标签中,就像加载的文件。

无需对JPEG进行两次编码(第一次是在AS3中,然后是第二次在TypeScript中,这只是在破坏图像数据)

(1)首先像在原始AS3代码中那样创建JPEG,然后(2)在TypeScript或HTML方面,检查前三个值已授予您(使用alertconsole.log选项)...

downloadedImage.sData[0] //should be: 0xFF (or 255)
downloadedImage.sData[1] //should be: 0xD8 (or 216)
downloadedImage.sData[2] //should be: 0xFF (or 255)

这3个值是JPEG标头的正确且预期的开始字节(表明您的数据确实是有效的JPEG图像)。

在HTML的<body>部分中,确保您有一个<image>标签,等待字节图像添加为.src ...

<body>

<img id="myPic" src="none.jpg" width="600" height="400">

</body>

然后使用JavaScript(我不知道TypeScript,所以您将自己转换这部分)

<script>

//# downloadedImage.sData String must look like "0xFF,0xD8,0xFF" etc (using 0xFF or 0xff is same result)
var myArr = new Uint8Array( [ downloadedImage.sData ] );

var blob = new Blob( [downloadedImage.sData],{ type: "image/jpeg" } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
var img = document.getElementById( "myPic" );
img.src = imageUrl;

</script>

希望这对获得工作结果很有用。

PS:一些完整的可测试示例代码(仅HTML / JS,没有TypeScript)...

<!DOCTYPE html>
<html>
<body>

<img id="myPic" src="none.jpg" width="600" height="400">

</body>

<script>

//# fill the array properly & fully,below is just small example of expected values
var myArr = new Uint8Array( [0xFF,0xFF,0xE0,0x00 ... 0xFF,0xD9]);

var blob = new Blob( [myArr],{ type: "image/jpeg" } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
var img = document.getElementById( "myPic" );
img.src = imageUrl;

</script>

</html>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。