Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Delphi TBitmap to string via TBitmapSurface and back to TBitmap


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 8 - Last Post: Jun 4, 2016 2:15 PM Last Post By: Md. Shariful Al...
Md. Shariful Al...

Posts: 70
Registered: 9/9/01
Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 8:06 AM
I am doing following to convert TBitmap(Firemonkey) to string:
function BitmapToBase64(Bitmap: Tbitmap): string;
var
BS: TBitmapSurface;
AStream: TMemoryStream;
begin
BS := TBitmapSurface.Create;
BS.Assign(Bitmap);
BS.SetSize(300, 200);
AStream := TMemoryStream.Create;
try
TBitmapCodecManager.SaveToStream(AStream, BS, '.png');
Result := TNetEncoding.Base64.EncodeBytesToString(AStream.Memory, AStream.Size);//as per Remy Lebeau on stackoverflow http://stackoverflow.com/questions/37602538/delphi-tbitmap-to-string-via-tbitmapsurface-and-back-to-tbitmap/37602972
finally
AStream.Free;
BS.Free;
end;
end;

How can I revert the string back to TBitmap? I did following which doesn't produce TBitmap:
procedure Base64ToBitmap(AString: String; Result : Tbitmap);
var
ms : TMemoryStream;
BS: TBitmapSurface;
bytes : TBytes;
begin
bytes := TNetEncoding.Base64.DecodeStringToBytes(AString);
ms := TMemoryStream.Create;
try
ms.WriteData(bytes, Length(bytes));
ms.Position := 0;
BS := TBitmapSurface.Create;
BS.SetSize(300, 200);
try
TBitmapCodecManager.LoadFromStream(ms, bs);
Result.Assign(bs);
finally
BS.Free;
end;
finally
ms.Free;
end;
end;

I need smaller size of base64 string so that I can transmit it to Datasnap server. Normal base64 string gives me Out of memory as size of string goes greater then 200000 - 1000000 in length.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 8:35 AM   in response to: Md. Shariful Al... in response to: Md. Shariful Al...
Md. Shariful Alam Khan wrote:

I need smaller size of base64 string so that I can transmit
it to Datasnap server.

As I already told you several times on SO, the only way to make a smaller
base64 string is to compress the PNG data before you encode it to base64,
otherwise use a more condensed string encoding format, like yEnc.

--
Remy Lebeau (TeamB)
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 8:36 AM   in response to: Md. Shariful Al... in response to: Md. Shariful Al...
Hello,

please do stop to convert Bitmaps to strings and then attempt to convert
tthem back.

Strings are not meant to be binary buffers of any sort and thus somebody
can easily corrupt your data as conversions might take place out of your
control. Even if it seems to work initially it may fail in some cases
and then you're hunting quite hard to find issues.

Do please use TBytes or TStream and descendants for this!
Please do us all that favour. We'll gladly help you using the proposed
stuff, but strings? You won't find many here helping you nusing those
for storing TBitmap data in.

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 9:28 AM   in response to: Markus Humm in response to: Markus Humm
Markus wrote:

Strings are not meant to be binary buffers of any sort and thus
somebody can easily corrupt your data as conversions might take
place out of your control.

That is not the issue in this case, as the string is not being used as a
binary buffer. The source bitmap is being saved as a PNG that is then encoded
as base64 for transmission, then the received base64 is decoded back to PNG
and loaded into the destination bitmap.

--
Remy Lebeau (TeamB)
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 1:26 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Am 03.06.2016 um 18:28 schrieb Remy Lebeau (TeamB):
Markus wrote:

Strings are not meant to be binary buffers of any sort and thus
somebody can easily corrupt your data as conversions might take
place out of your control.

That is not the issue in this case, as the string is not being used as a
binary buffer. The source bitmap is being saved as a PNG that is then encoded
as base64 for transmission, then the received base64 is decoded back to PNG
and loaded into the destination bitmap.

Hello,

ok, understood. But why not avoid the conversion to and from base64
completely? Doesn't datasnap support something binary as well?

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 3, 2016 1:32 PM   in response to: Markus Humm in response to: Markus Humm
Markus wrote:

ok, understood. But why not avoid the conversion to and from base64
completely? Doesn't datasnap support something binary as well?

I don't know, I've never used DataSnap before. IIRC, it does support sending
TStream object.

--
Remy Lebeau (TeamB)
Md. Shariful Al...

Posts: 70
Registered: 9/9/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 4, 2016 12:01 AM   in response to: Markus Humm in response to: Markus Humm
It does support through BroadcastObjectToChannel but when ever you want to broadcast TBitmap/TMemoryStream it raised exception with tkInterface/tkSet not yet supported. Only supporting thing is string & TObject. Also tried to put TBitmap in TObject but it doesn't get value of TObject. Don't understand why TBitmap treat as tkInterface and TMemoryStream treat as tkSet.
Markus Humm wrote:
Am 03.06.2016 um 18:28 schrieb Remy Lebeau (TeamB):
Markus wrote:

Strings are not meant to be binary buffers of any sort and thus
somebody can easily corrupt your data as conversions might take
place out of your control.

That is not the issue in this case, as the string is not being used as a
binary buffer. The source bitmap is being saved as a PNG that is then encoded
as base64 for transmission, then the received base64 is decoded back to PNG
and loaded into the destination bitmap.

Hello,

ok, understood. But why not avoid the conversion to and from base64
completely? Doesn't datasnap support something binary as well?

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 4, 2016 11:58 AM   in response to: Md. Shariful Al... in response to: Md. Shariful Al...
Md. Shariful Alam Khan wrote:

It does support through BroadcastObjectToChannel but when ever
you want to broadcast TBitmap/TMemoryStream it raised exception
with tkInterface/tkSet not yet supported.

Then you need to talk to Embarcadero about that, because that is clearly
a bug they need to fix.

Only supporting thing is string & TObject.

All objects in Delphi are based on TObject.

Don't understand why TBitmap treat as tkInterface and TMemoryStream
treat as tkSet.

Have you tried stepping through the RTL/FMX source code with the debugger
to find out exactly why it behaves like that?

--
Remy Lebeau (TeamB)
Md. Shariful Al...

Posts: 70
Registered: 9/9/01
Re: Delphi TBitmap to string via TBitmapSurface and back to TBitmap  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 4, 2016 2:15 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Now I tried with TBytes which worked perfectly without any AV. I think TBytes is better than TBitmap/TMemoryStream and other. The exception raised in DBXReflector unit.
Remy Lebeau (TeamB) wrote:
Md. Shariful Alam Khan wrote:

It does support through BroadcastObjectToChannel but when ever
you want to broadcast TBitmap/TMemoryStream it raised exception
with tkInterface/tkSet not yet supported.

Then you need to talk to Embarcadero about that, because that is clearly
a bug they need to fix.

Only supporting thing is string & TObject.

All objects in Delphi are based on TObject.

Don't understand why TBitmap treat as tkInterface and TMemoryStream
treat as tkSet.

Have you tried stepping through the RTL/FMX source code with the debugger
to find out exactly why it behaves like that?

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02