Brandon
2015-02-02 04:47:11
I wrote a class for Simba to allow Bitmaps with the alpha channel. All you have to do is change SMART to also use it.
To do this, I opened Client.java and replaced: BufferedImage.TYPE_INT_RGB with BufferedImage.TYPE_INT_ARGB and recompiled Smart. All you need is the new SMART.jar. NOTE: You can also draw transparent images on the browser or any window as well..
Next, I wrote the following class to load images manually:
Example Results:


Saving Bitmaps to disk (You can see that it has a transparent background):
and it's a BITMAP.. Not a PNG.
Properties:

Photoviewer shows the background as transparent as well..

You can use this site to convert a PNG to a 32-bit bitmap (I use my own program to convert): http://www.picresize.com/
OR pray that someone adds Alpha support to Simba.. Enjoy.
NOTES:
The code above does not require explicit memory allocation. This means that if something crashes, you don't have a leak. You never have to free anything either because there's nothing to free. The only time freeing of anything is required is if you convert to TMufasaBitmap. That's when you free the resulting TMufasaBitmap. NOT the bitmap belonging to this API.
I also doubt TMufasaBitmap would need freeing as it doesn't allocate memory for bitmap pointers. But who knows.. There's also a ToString and FromString function to allow you to store and create bitmaps to/from strings.
To do this, I opened Client.java and replaced: BufferedImage.TYPE_INT_RGB with BufferedImage.TYPE_INT_ARGB and recompiled Smart. All you need is the new SMART.jar. NOTE: You can also draw transparent images on the browser or any window as well..
Next, I wrote the following class to load images manually:
type
TBitmap32 = record
Pixels: array of byte;
W, H: Integer;
end;
Procedure TBitmap32.Init(W, H: Integer);
Begin
Self.W := W;
Self.H := H;
SetLength(Pixels, ((Self.W * $20 + $1F) div $20) * $4 * Self.H);
End;
Procedure TBitmap32.Init(Path: String); overload;
type PInt = ^Integer;
var
Stream: TFileStream;
Header: array[0..53] of byte;
Offset, Size: Integer;
Begin
try
Stream.Init(Path, $0000);
Stream.Read(Header, sizeof(Header));
If ((Header[0] = $42) and (Header[1] = $4D) and (Header[28] = $20)) Then
begin
Self.W := PInt(@Header[18])^;
Self.H := PInt(@Header[22])^;
Offset := PInt(@header[10])^;
Size := ((Self.W * Header[28] + $1F) div $20) * $4 * Self.H;
Stream.Seek(Offset, soBeginning);
SetLength(Self.Pixels, Size);
Stream.Read(Self.Pixels[0], Size);
Self.Flip();
end;
finally
Stream.Free;
end;
End;
Procedure TBitmap32.Save(Path: String);
type PInt = ^Integer;
var
Stream: TFileStream;
I, Size: Integer;
Begin
try
Self.Flip();
Stream.Init(Path, $FF00);
Size := ((Self.W * $20 + $1F) div $20) * $4 * Self.H;
Stream.WriteWord($4D42);
{$IFNDEF BHEXTENDED}
Stream.WriteDWord(Size + $7A);
{$ELSE}
Stream.WriteDWord(Size + $8A);
{$ENDIF}
Stream.WriteDWord($0);
{$IFNDEF BHEXTENDED}
Stream.WriteDWord($7A);
Stream.WriteDWord($6C);
{$ELSE}
Stream.WriteDWord($8A);
Stream.WriteDWord($7C);
{$ENDIF}
Stream.WriteDWord(Self.W);
Stream.WriteDWord(Self.H);
Stream.WriteWord($1);
Stream.WriteWord($20);
Stream.WriteDWord($3);
Stream.WriteDWord(Size);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($FF0000);
Stream.WriteDWord($FF00);
Stream.WriteDWord($FF);
Stream.WriteDWord($FF000000);
Stream.WriteDWord($73524742);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
{$IFDEF BHEXTENDED}
Stream.WriteDWord($4);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
Stream.WriteDWord($0);
{$ENDIF}
Stream.WriteBuffer(Self.Pixels[0], Size);
finally
Stream.Free;
end;
End;
Procedure TBitmap32.Flip();
var
I, J: Integer;
Ptr: ^PtrUInt;
Begin
Ptr := @Self.Pixels[0];
For I := 0 To (Self.H div 2) - 1 do
For J := 0 To Self.W - 1 Do
Swap(Ptr[(Self.H - I - 1) * Self.W + J]^, Ptr[I * Self.W + J]^);
End;
Function TBitmap32.GetMufasaBitmap(): TMufasaBitmap;
Begin
Result.Init(Client.GetMBitmaps);
Result.SetPersistentMemory(PtrUInt(@Self.Pixels[0]), Self.W, Self.H);
End;
Function TBitmap32.Copy(): TBitmap32;
Begin
Result.W := Self.W;
Result.H := Self.H;
Result.Pixels := Self.Pixels;
End;
Function TBitmap32.GetPixel(X, Y: Integer): TColor;
type
TColour32 = Union Colour: Integer; RGB: TRGB32; end;
var
Ptr: ^TColour32;
Begin
Ptr := @Self.Pixels[0];
Result := Ptr[Y * Self.W + X]^.Colour;
Result := (Result and $FF000000) or ((Result and $FF0000) shr 16) or (Result and $00FF00) or ((Result and $0000FF) shl 16);
End;
Procedure TBitmap32.SetPixel(X, Y: Integer; Colour: TColor);
type
TColour32 = Union Colour: Integer; RGB: TRGB32; end;
PColour32 = ^TColour32;
var
Ptr: ^TColour32;
Begin
Ptr := @Self.Pixels[0];
Colour := (Colour and $FF000000) or ((Colour and $FF0000) shr 16) or (Colour and $00FF00) or ((Colour and $0000FF) shl 16);
Ptr[Y * Self.W + X]^.Colour := Colour;
End;
Procedure TBitmap32.GetPixel(X, Y: Integer; var R, G, B, A: Byte) overload;
type
TColour32 = Union Colour: Integer; RGB: TRGB32; end;
PColour32 = ^TColour32;
var
Ptr: ^TColour32;
Begin
Ptr := @Self.Pixels[0];
R := Ptr[Y * Self.W + X]^.RGB.R;
G := Ptr[Y * Self.W + X]^.RGB.G;
B := Ptr[Y * Self.W + X]^.RGB.B;
A := Ptr[Y * Self.W + X]^.RGB.A;
End;
Procedure TBitmap32.SetPixel(X, Y: Integer; R, G, B, A: Byte) overload;
type
TColour32 = Union Colour: Integer; RGB: TRGB32; end;
PColour32 = ^TColour32;
var
Ptr: ^TColour32;
Begin
Ptr := @Self.Pixels[0];
Ptr[Y * Self.W + X]^.RGB.R := R;
Ptr[Y * Self.W + X]^.RGB.G := G;
Ptr[Y * Self.W + X]^.RGB.B := B;
Ptr[Y * Self.W + X]^.RGB.A := A;
End;
Procedure TBitmap32.FromString(const Data: String);
type PInt = ^Integer;
var
Str: String;
I: Integer;
O: Integer;
Begin
If (Data[1] = 'm') Then
begin
O := sizeof(Integer) * 2;
Str := DecompressString(Base64Decode(Copy(Data, 2, Length(Data) - 1)));
SetLength(Self.Pixels, Length(Str));
Self.W := PInt(@Str[1])^;
Self.H := PInt(@Str[5])^;
For I := O + 1 To Length(Str) Do
Self.Pixels[I - 1] := Byte(Str[I]);
end;
End;
Function TBitmap32.ToString(): String;
type PInt = ^Integer;
var
Str: String;
I: Integer;
O: Integer;
Begin
O := sizeof(Integer) * 2;
SetLength(Str, Length(Self.Pixels) + O);
PInt(@Str[1])^ := Self.W;
PInt(@Str[5])^ := Self.H;
For I := O + 1 To Length(Self.Pixels) Do
Str[I] := AnsiChar(Self.Pixels[I - 1]);
Result := 'm' + Base64Encode(CompressString(Str));
End;
Function ToString(var Bmp: TBitmap32): String; override;
begin
Result := Bmp.ToString();
end;
//Just a test function.. Not part of the API.
Procedure SetAlphas(var Bmp: TBitmap32; ADiv: Integer);
var
I, J: Integer;
R, G, B, A: Byte;
Begin
For I := 0 To Bmp.H - 1 Do
For J := 0 To Bmp.W - 1 Do
Begin
Bmp.GetPixel(J, I, R, G, B, A);
Bmp.SetPixel(J, I, R, G, B, A div ADiv);
End;
End;
var
Smart: TSmart;
TBmp: TBitmap32;
TMBmp: TMufasaBitmap;
begin
ClearDebug();
Smart.Create(800, 600);
Smart.Graphics().Clear();
TBmp.Init('C:/Users/Brandon/Desktop/Small.bmp');
SetAlphas(TBmp, 100);
TMBmp := TBmp.GetMufasaBitmap();
Smart.Graphics().DrawBitmap(TMBmp.getIndex(), Point(175, 100));
TMBmp.Free();
end.
Example Results:


Saving Bitmaps to disk (You can see that it has a transparent background):
and it's a BITMAP.. Not a PNG.Properties:

Photoviewer shows the background as transparent as well..

You can use this site to convert a PNG to a 32-bit bitmap (I use my own program to convert): http://www.picresize.com/
OR pray that someone adds Alpha support to Simba.. Enjoy.
NOTES:
The code above does not require explicit memory allocation. This means that if something crashes, you don't have a leak. You never have to free anything either because there's nothing to free. The only time freeing of anything is required is if you convert to TMufasaBitmap. That's when you free the resulting TMufasaBitmap. NOT the bitmap belonging to this API.
I also doubt TMufasaBitmap would need freeing as it doesn't allocate memory for bitmap pointers. But who knows.. There's also a ToString and FromString function to allow you to store and create bitmaps to/from strings.