用loader.loadbytes直接load bitmapdata.getpixels产生的bytearray
2010-06-14 21:01 宝宝合凤凰 阅读(2332) 评论(1) 编辑 收藏 举报
bitmapdata.getpixel方法是ActionScript 3.0中的一个新方法,可以把矩形内的像素读取成bytearray,但是这种bytearray又不能直接用loader.loadbytes来读,一读就会出现IOERROR。
为了达到可以直接用loader.loadbytes读取的目的,找了一下百度和GOOGLE,找到了以下方法,有需要的可以用用。
PS 以下代码转自互联网,牛C网只负责整理
/*
Copyright (c) 2007 Trevor McCauley - www.senocular.com
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS or IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS or COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES or OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT or OTHERWISE, ARISING
FROM, OUT OF or IN CONNECTION WITH THE SOFTWARE or THE USE or
OTHER DEALINGS IN THE SOFTWARE.
*/
package com.senocular.images {
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class BMPEncoder {
/**
* Converts a BitmapData instance into a 32-bit
* BMP image.
* @param bitmapData A BitmapData instance of the image
* desired to have converted into a Bitmap (BMP).
* @return A ByteArray containing the binary Bitmap (BMP)
* representation of the BitmapData instance passed.
*/
public static function encode(bitmapData:BitmapData):ByteArray {
// image/file properties
var bmpWidth:int = bitmapData.width;
var bmpHeight:int = bitmapData.height;
var imageBytes:ByteArray = bitmapData.getPixels(bitmapData.rect);
var imageSize:int = imageBytes.length;
var imageDataOffset:int = 0x36;
var fileSize:int = imageSize + imageDataOffset;
// binary BMP data
var bmpBytes:ByteArray = new ByteArray();
bmpBytes.endian = Endian.LITTLE_ENDIAN; // byte order
// header information
bmpBytes.length = fileSize;
bmpBytes.writeByte(0x42); // B
bmpBytes.writeByte(0x4D); // M (BMP identifier)
bmpBytes.writeInt(fileSize); // file size
bmpBytes.position = 0x0A; // offset to image data
bmpBytes.writeInt(imageDataOffset);
bmpBytes.writeInt(0x28); // header size
bmpBytes.position = 0x12; // width, height
bmpBytes.writeInt(bmpWidth);
bmpBytes.writeInt(bmpHeight);
bmpBytes.writeShort(1); // planes (1)
bmpBytes.writeShort(32); // color depth (32 bit)
bmpBytes.writeInt(0); // compression type
bmpBytes.writeInt(imageSize); // image data size
bmpBytes.position = imageDataOffset; // start of image data...
// write pixel bytes in upside-down order
// (as per BMP format)
var col:int = bmpWidth;
var row:int = bmpHeight;
var rowLength:int = col * 4; // 4 bytes per pixel (32 bit)
try {
// make sure we're starting at the
// beginning of the image data
imageBytes.position = 0;
// bottom row up
while (row--) {
// from end of file up to imageDataOffset
bmpBytes.position = imageDataOffset + row*rowLength;
// read through each column writing
// those bits to the image in normal
// left to rightorder
col = bmpWidth;
while (col--) {
bmpBytes.writeInt(imageBytes.readInt());
}
}
}catch(error:Error){
// end of file
}
// return BMP file
return bmpBytes;
}
}
}
Copyright (c) 2007 Trevor McCauley - www.senocular.com
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS or IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS or COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES or OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT or OTHERWISE, ARISING
FROM, OUT OF or IN CONNECTION WITH THE SOFTWARE or THE USE or
OTHER DEALINGS IN THE SOFTWARE.
*/
package com.senocular.images {
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class BMPEncoder {
/**
* Converts a BitmapData instance into a 32-bit
* BMP image.
* @param bitmapData A BitmapData instance of the image
* desired to have converted into a Bitmap (BMP).
* @return A ByteArray containing the binary Bitmap (BMP)
* representation of the BitmapData instance passed.
*/
public static function encode(bitmapData:BitmapData):ByteArray {
// image/file properties
var bmpWidth:int = bitmapData.width;
var bmpHeight:int = bitmapData.height;
var imageBytes:ByteArray = bitmapData.getPixels(bitmapData.rect);
var imageSize:int = imageBytes.length;
var imageDataOffset:int = 0x36;
var fileSize:int = imageSize + imageDataOffset;
// binary BMP data
var bmpBytes:ByteArray = new ByteArray();
bmpBytes.endian = Endian.LITTLE_ENDIAN; // byte order
// header information
bmpBytes.length = fileSize;
bmpBytes.writeByte(0x42); // B
bmpBytes.writeByte(0x4D); // M (BMP identifier)
bmpBytes.writeInt(fileSize); // file size
bmpBytes.position = 0x0A; // offset to image data
bmpBytes.writeInt(imageDataOffset);
bmpBytes.writeInt(0x28); // header size
bmpBytes.position = 0x12; // width, height
bmpBytes.writeInt(bmpWidth);
bmpBytes.writeInt(bmpHeight);
bmpBytes.writeShort(1); // planes (1)
bmpBytes.writeShort(32); // color depth (32 bit)
bmpBytes.writeInt(0); // compression type
bmpBytes.writeInt(imageSize); // image data size
bmpBytes.position = imageDataOffset; // start of image data...
// write pixel bytes in upside-down order
// (as per BMP format)
var col:int = bmpWidth;
var row:int = bmpHeight;
var rowLength:int = col * 4; // 4 bytes per pixel (32 bit)
try {
// make sure we're starting at the
// beginning of the image data
imageBytes.position = 0;
// bottom row up
while (row--) {
// from end of file up to imageDataOffset
bmpBytes.position = imageDataOffset + row*rowLength;
// read through each column writing
// those bits to the image in normal
// left to rightorder
col = bmpWidth;
while (col--) {
bmpBytes.writeInt(imageBytes.readInt());
}
}
}catch(error:Error){
// end of file
}
// return BMP file
return bmpBytes;
}
}
}
===================================
习惯上,我们是用 Loader 加载可视的文件,例如 jpg、png、swf 等等。但个别情况下,我们还需要对已加载文件的二进制数据进行处理,这种情况下我第一时间想到的就是 URLLoader 类。在我的脑里习惯上是这样认为的:Loader 的工作是把可视文件显示在舞台上,而 URLLoader 的工作是获得任何文件的二进制数据,但其实不然。对于图片和 swf 文件,既想把它们放到显示列表又想对其二进制数据进行处理,只使用 Loader 即可。其二进制数据由 Loader.contentLoaderInfo.bytes 间接获得。为什么说间接?因为 Loader.contentLoaderInfo.bytes 不完全是文件的原始二进制数据(ByteArray)。Flash Player 对其进行处理过。
事实上,Loader.contentLoaderInfo.bytes 是一个符合 SWF 文件格式的二进制数据。你可以做一个测试:用 Loader 加载一张图片后,使用 FileReference.save() 方法把 Loader.contentLoaderInfo.bytes 保存到本地,扩展名为“.swf”。你可以用 Flash Player 成功地打开它。甚至,你还可以按照 SWF 文件格式解析 Loader.contentLoaderInfo.bytes 。
那么,使用 Loader 加载一张图片,要如何才能获得图片的原始二进制数据呢?我做过测试,去掉 Loader.contentLoaderInfo.bytes 最前的 45 字节和最后的 17 字节,剩下中间部分就是图片的原始二进制数据了。