There are some time ago, we have developed an AS3-AIR class, for reading and writing Windows bitmap file.
MswBMPCodec.as Class file content :
package msw.asBitmap
{
import flash.display.BitmapData;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class MswBMPCodec
{
private const MASK : int = 0xFF;
public var FileData : Object;
//****************************************************
// Class Constructor !!!
//****************************************************
public function MswBMPCodec()
{
FileData = new Object();
super();
}
//****************************************************
// Function Read BMP file with path
//****************************************************
public function ReadBMPWithFilename(filename : String ) : BitmapData {
var BmpFile : File = new File(filename);
return ReadBMP( BmpFile );
}
//****************************************************
// Function Read BMP file with File
//****************************************************
public function ReadBMP(BmpFile : File) : BitmapData {
var BufferedImage : BitmapData;
try{
var I : int;
var J : int;
var K : int
var Blue : int = 0;
var Red : int = 0;
var Green : int = 0;
var Alpha : int = 0;
var Bytes : ByteArray = new ByteArray();
Bytes.endian = Endian.LITTLE_ENDIAN;
var BmpStream : FileStream = new FileStream();
BmpStream.open(BmpFile, FileMode.READ);
BmpStream.position = 0;
BmpStream.readBytes(Bytes, 0, BmpFile.size );
BmpStream.close();
//------------------------------------------------------
// La signature (sur 2 octets), indiquant qu'il s'agit
// d'un fichier BMP à l'aide des deux caractères.
// BM,indique qu'il s'agit d'un Bitmap Windows.
// BA indique qu'il s'agit d'un Bitmap OS/2.
// CI indique qu'il s'agit d'une icone couleur OS/2.
// CP indique qu'il s'agit d'un pointeur de couleur OS/2.
// IC indique qu'il s'agit d'une icone OS/2.
// PT indique qu'il s'agit d'un pointeur OS/2.
//------------------------------------------------------
FileData.signature = Bytes.readShort();
if (FileData.signature != 0x4D42){
return null;
}
//------------------------------------------------------
// La taille totale du fichier en octets (4 octets)
//------------------------------------------------------
FileData.size = Bytes.readInt();
//------------------------------------------------------
// Un champ réservé (4 octets)
//------------------------------------------------------
FileData.reserved = Bytes.readInt();
//------------------------------------------------------
// L'offset de l'image (4 octets), c'est-à-dire
// l'adresse relative du début des informations concernant
// l'image par rapport au début du fichier
//------------------------------------------------------
FileData.offset = Bytes.readInt();
//------------------------------------------------------
// La taille de l'entête de l'image en octets (4 octets).
// Les valeurs hexadécimales suivantes sont possibles
// suivant le type de format BMP :
// 28 pour Windows 3.1x, 95, NT, ...
// 0C pour OS/2 1.x
// F0 pour OS/2 2.x
//------------------------------------------------------
FileData.headerSize = Bytes.readInt();
if (FileData.headerSize != 0x28){
return null;
}
//------------------------------------------------------
// La largeur de l'image (4 octets), c'est-à-dire le
// nombre de pixels horizontalement
//------------------------------------------------------
FileData.width = Bytes.readInt();
//------------------------------------------------------
//La hauteur de l'image (4 octets), c'est-à-dire le
// nombre de pixels verticalement
//------------------------------------------------------
FileData.height = Bytes.readInt();
//------------------------------------------------------
// Le nombre de plans (2 octets). Cette valeur vaut
// toujours 1
//------------------------------------------------------
FileData.mapCount = Bytes.readShort();
//------------------------------------------------------
// La profondeur de codage de la couleur (2 octets),
// c'est-à-dire le nombre de bits utilisés pour coder la
// couleur. Cette valeur peut-être égale à 1, 4, 8, 16,
// 24 ou 32
//------------------------------------------------------
FileData.byteDepth = Bytes.readShort();
if (FileData.byteDepth < 24){
return null;
}
//------------------------------------------------------
// La méthode de compression (4 octets). Cette valeur
// vaut 0 lorsque l'image n'est pas compressée,
// ou bien 1, 2, 3 ou 4 suivant le type de compression
// utilisé :
// 0 pas de compression
// 1 pour un codage RLE de 8 bits par pixel
// 2 pour un codage RLE de 4 bits par pixel
// 3 pour un codage bitfields, signifiant que la couleur
// est codé par un triple masque représenté par la palette
// 3 pour un codage Huffman, signifiant 1-bit-per-pixel
// modified Huffman compression
// 4 pour un codage RLE de 24 bits par pixel
//------------------------------------------------------
FileData.compression = Bytes.readInt();
//------------------------------------------------------
// La taille totale de l'image en octets (4 octets).
//------------------------------------------------------
FileData.imageSize = Bytes.readInt();
//------------------------------------------------------
// La résolution horizontale (4 octets), c'est-à-dire
// le nombre de pixels par mètre horizontalement
//------------------------------------------------------
FileData.horizontalResolution = Bytes.readInt();
//------------------------------------------------------
// La résolution verticale (4 octets), c'est-à-dire
// le nombre de pixels par mètre verticalement
//------------------------------------------------------
FileData.verticalResolution = Bytes.readInt();
//------------------------------------------------------
// Le nombre de couleurs de la palette (4 octets)
//------------------------------------------------------
FileData.colorPaletteCount = Bytes.readInt();
//------------------------------------------------------
// Le nombre de couleurs importantes de la palette
// (4 octets). Ce champ peut être égal à 0 lorsque
// chaque couleur a son importance.
//------------------------------------------------------
FileData.significantColorsCount = Bytes.readInt();
if (FileData.colorPaletteCount > 0){
var ColorArray : Array = new Array();
for(var loop : int = 1; loop = 4*FileData.colorPaletteCount; loop ++){
Blue = Bytes.readUnsignedByte();
Green = Bytes.readUnsignedByte();
Red = Bytes.readUnsignedByte();
Alpha = Bytes.readUnsignedByte();
ColorArray.push(256*256*Red + 256*Green+Blue);
}
FileData.paletteColor = ColorArray;
}
//------------------------------------------------------
// Lecture des Données !!!
//------------------------------------------------------
Bytes.position = FileData.offset;
switch(FileData.byteDepth) {
case 24:
BufferedImage = new BitmapData(FileData.width, FileData.height, false, 0x000000);
break;
case 32:
BufferedImage = new BitmapData(FileData.width, FileData.height, true, 0x00000000);
break;
}
var JunkCount : int = (FileData.width * 3) % 4;
switch(FileData.byteDepth) {
case 24:
for(J = FileData.height - 1; J >= 0; J--){
for(I = 0; I < FileData.width ; I++){
Blue = Bytes.readUnsignedByte();
Green = Bytes.readUnsignedByte();
Red = Bytes.readUnsignedByte();
BufferedImage.setPixel( I, J, 256*256*Red + 256*Green + Blue);
}
for(K = 0; K < JunkCount; K++){
Bytes.readUnsignedByte();
}
}
break;
case 32:
for(J = FileData.height - 1; J >= 0; J--){
for(I = 0; I < FileData.width; I++){
Blue = Bytes.readUnsignedByte();
Green = Bytes.readUnsignedByte();
Red = Bytes.readUnsignedByte();
Alpha = Bytes.readUnsignedByte();
BufferedImage.setPixel32( I, J, 256*256*256*Alpha + 256*256*Red + 256*Green + Blue);
}
}
break;
}
} catch(e:Error){
} finally {}
return BufferedImage;
}
//****************************************************
// Function Write BMP file with path
//****************************************************
public function writeBMPWithFilename(BufferedImage : BitmapData, filename : String ) : Boolean {
var BmpFile : File = new File(filename);
return writeBMP(BufferedImage, BmpFile);
}
//****************************************************
// Function Write BMP file with File
//****************************************************
public function writeBMP(BufferedImage : BitmapData, BmpFile : File) : Boolean {
try{
var Result : Boolean = true;
var Width : int = BufferedImage.width;
var Height : int = BufferedImage.height;
var Bytes : ByteArray = new ByteArray();
Bytes.endian = Endian.LITTLE_ENDIAN;
//------------------------------------------------------
// La signature (sur 2 octets), indiquant qu'il s'agit
// d'un fichier BMP à l'aide des deux caractères.
// BM,indique qu'il s'agit d'un Bitmap Windows.
//------------------------------------------------------
Bytes.writeShort(0x424D);
//------------------------------------------------------
// La taille totale du fichier en octets (4 octets)
//------------------------------------------------------
Bytes.writeUnsignedInt(Width*Height*4 + 0x36);
//------------------------------------------------------
// Un champ réservé (sur 4 octets)
//------------------------------------------------------
Bytes.writeUnsignedInt(0x00);
//------------------------------------------------------
// L'offset de l'image (4 octets), c'est-à-dire
// l'adresse relative du début des informations concernant
// l'image par rapport au début du fichier
//------------------------------------------------------
Bytes.writeUnsignedInt(0x36);
//------------------------------------------------------
// La taille de l'entête de l'image en octets (4 octets).
// Les valeurs hexadécimales suivantes sont possibles
// suivant le type de format BMP :
// 28 pour Windows 3.1x, 95, NT, ...
// 0C pour OS/2 1.x
// F0 pour OS/2 2.x
//------------------------------------------------------
Bytes.writeUnsignedInt(0x28);
//------------------------------------------------------
// La largeur de l'image (4 octets), c'est-à-dire
// le nombre de pixels horizontalement
//------------------------------------------------------
Bytes.writeUnsignedInt(Width);
//------------------------------------------------------
//La hauteur de l'image (4 octets), c'est-à-dire
// le nombre de pixels verticalement
//------------------------------------------------------
Bytes.writeUnsignedInt(Height);
//------------------------------------------------------
// Le nombre de plans (2 octets). Cette valeur vaut
// toujours 1
//------------------------------------------------------
Bytes.writeShort(0x01);
//------------------------------------------------------
// La profondeur de codage de la couleur(2 octets),
// c'est-à-dire le nombre de bits utilisés pour coder
// la couleur. Cette valeur peut-être égale à 1, 4, 8,
// 16, 24 ou 32
//------------------------------------------------------
Bytes.writeShort(0x20);
//------------------------------------------------------
// La méthode de compression (4 octets). Cette valeur
// vaut 0 lorsque l'image n'est pas compressée,
// ou bien 1, 2 ou 3 suivant le type de compression
// utilisé :
// 0 pas de compression
// 1 pour un codage RLE de 8 bits par pixel
// 2 pour un codage RLE de 4 bits par pixel
// 3 pour un codage bitfields, signifiant que la couleur
// est codé par un triple masque représenté par la palette
// 3 pour un codage Huffman, signifiant 1-bit-per-pixel
// modified Huffman compression
// 4 pour un codage RLE de 24 bits par pixel
//------------------------------------------------------
Bytes.writeUnsignedInt(0x00);
//------------------------------------------------------
// La taille totale de l'image en octets (4 octets).
//------------------------------------------------------
Bytes.writeUnsignedInt(Width*Height*4);
//------------------------------------------------------
// La résolution horizontale (4 octets), c'est-à-dire
// le nombre de pixels par mètre horizontalement
//------------------------------------------------------
Bytes.writeUnsignedInt(0x0EC4);
//------------------------------------------------------
// La résolution verticale (4 octets), c'est-à-dire
// le nombre de pixels par mètre verticalement
//------------------------------------------------------
Bytes.writeUnsignedInt(0x0EC4);
//------------------------------------------------------
// Le nombre de couleurs de la palette (4 octets)
//------------------------------------------------------
Bytes.writeUnsignedInt(0x00);
//------------------------------------------------------
// Le nombre de couleurs importantes de la palette
// (4 octets). Ce champ peut être égal à 0 lorsque
// chaque couleur a son importance.
//------------------------------------------------------
Bytes.writeUnsignedInt(0x00);
//------------------------------------------------------
//Ecriture du corps du fichier BMP
//------------------------------------------------------
for (var Y : int = Height - 1; Y >= 0; Y--) {
for (var X : int = 0; X < Width; X++) {
Bytes.writeUnsignedInt( BufferedImage.getPixel32(X,Y) );
}
}
//------------------------------------------------------
// Enregistrement du fichier
//------------------------------------------------------
var BmpStream : FileStream = new FileStream();
BmpStream.open(BmpFile, FileMode.WRITE);
BmpStream.position = 0;
BmpStream.writeBytes(Bytes);
BmpStream.close();
return true;
} catch(e:Error){
return false;
}
return true;
}
}
}
Use : (Functions written on the fly and not tested!)
import msw.asBitmap.MswBMPCodec;
....
public function ConvertBmpToJpg(BmpFile: File, JpgFile : File) : void {
var BmpEncoder : MswBMPCodec = new MswBMPCodec();
var BmpBitmapData : BitmapData = BmpEncoder.ReadBMP(BmpFile);
var jpg : JPEGEncoder = new JPEGEncoder(100);
var ResByteArray : ByteArray = jpg.encode(BmpBitmapData);
var fileStream : FileStream = new FileStream();
fileStream.open(JpgFile, FileMode.WRITE);
fileStream.writeBytes(ResByteArray);
fileStream.close();
}
public function ConvertJpgToBmp(BmpFile: File, JpgFile : File) : void {
private function ImageLoadHandler(event : Event) : void {
event .target.removeEventListener(Event.COMPLETE, ImageLoadHandler)
var BmpEncoder : MswBMPCodec = new MswBMPCodec();
BmpEncoder.writeBMP(event .target.content.bitmapData, BmpFile);
}
var loader : Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ImageLoadHandler, false, 0, true)
loader.load( new URLRequest(JpgFile.url) );
}
You can download filesHERE.
