Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Delphi: How to decode Base64 encoded string into viewable bitmap image

Posted on 2008-06-12
6
Medium Priority
?
14,011 Views
Last Modified: 2013-11-23
Hi,

I'm referring to previous question titled Decode hex text file into viewable bitmap image, which targeted VB.NET development.
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_22710540.html

Does anybody know how to perform similar task in Delphi?

I also have a string encoded in Base64 , which is the result of capturing a signature image from a PDA. The string looks like below:

PRY7FTcUNBQyFjEYMhozHDYcNx84ITYjMyQxJS8kLSQtJP//QxJCFEIWQhlBG0EdQR9BIUMfQx///1YOVhBUD1IQUBBNEUwTSxZMGE0aTxxRHFMeVR9XHlgbWBlWGFMYURhPGE8Y//9gGl8YXxZfFF8SYBBgDmIPYxFkFGUXZhloFmgUaRFqDmoMagpqCv//Rz1HP0dBR0RGRkZJRktGTUZN//9NPE4+TkBOQ09FT0dQSlFMUEpPR09FTURLRUlFR0RHRP//WzxZO1Y9VD1SP1JBUkNTRVVHWEhaSFpI//9aQVhBVkFTQVFAUUD//2NEY0FiP2I8YjpiOGQ2ZjVoN2o5aztqPWk/Z0BkQGI+Y0BlQWdCakNsQ25EbkT//3w0eTR3NXQ2cjdwOW87cD1yP3RAdkJ4QnpDekP//3k5dzp1OnM6cTpuOW45//8=

here is what the PDA vendor says about the file:
-----------------------------------------------------------------
Ok, the data coming in is basically a list of lines to draw.

To make the data in the first place, a series of points that would create the lines of the signature are recorded, where any pen lift (i.e. the drawing stopped) is recorded as 255,255 to serve as a terminator.

This array of points is turned into a byte array (i.e. line from 2,3 to 40, 50 to 80, 3 becomes byte[] {2,3,40,50, 80, 3} )

This is run through a Microsoft call Convert.ToBase64String to cut down on size (ever seen how big an xml encoded byte array is?) and make it easier to pass the data back into a webservice via a string parameter.  The data will need to be de-converted from this form to get the byte array back out, that is then used to draw the lines in the code sample you supplied.
-----------------------------------------------------------------

How to convert this string back into a viewable Bitmap image using DELPHI? How about in PHP?

I believe that from the byte array, each pair is a point. So to draw the signature you just draw the points. So byte[0] =  31 and byte[1] = 102 is point 1. Then you would draw a line from this point to the next point which is byte[2] and byte[3] and then you would draw a line from this to the next point and so on.

They also sent us a function (in C#) to draw the byte array but how to convert this function into Delphi and PHP?

thanks
Anthony
using System;
using System.Drawing;
using System.Collections;
 
namespace ADS.WorkstationPC
{
	/// <summary>
	/// Summary description for SignatureToBitmap.
	/// </summary>
	public class SignatureToBitmap
	{
		private static SignatureToBitmap UniqueBitmap = new SignatureToBitmap();
		private SignatureToBitmap()
		{
			//
			// TODO: Add constructor logic here
			//
 
		}
		public static Bitmap GetBitmap(byte[] rawsignature)
		{
			Bitmap bmSignature = new Bitmap(254, 254);
			Graphics gr = Graphics.FromImage(bmSignature);
			Pen pen = new Pen(new SolidBrush(Color.Black), 1);
			ArrayList alline = new ArrayList();
			ArrayList alpoint = new ArrayList();
 
			foreach (byte abyte in rawsignature)
			{
				alpoint.Add((int)abyte);
				if (alpoint.Count > 1)
				{
					Point apoint = new Point((int)alpoint[0], (int)alpoint[1]);
					alpoint.Clear(); // clear the array list
					alline.Add(apoint); //adds to the end of the array list
					if (apoint.X == 255) 
						alline.Clear();
                    else if (alline.Count > 1)
					{
						Point firstpoint = (Point)alline[0]; //?
						alline.RemoveAt(0); // removes the element at that index
						gr.DrawLine(pen, firstpoint, apoint);
					}
				}
			}
 
			return bmSignature;
		}
	}
}

Open in new window

byte-array.gif
signature.gif
encodedstring.gif
0
Comment
Question by:COS_IT_AU
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
6 Comments
 
LVL 46

Expert Comment

by:aikimark
ID: 21783706
Is the Base64 decoding a problem?  If so, please look at the decoding routine found on this Torry's page:
http://www.swissdelphicenter.ch/torry/showcode.php?id=1524

When you reach this statement:
     x := x mod 256;
You will have the numeric value you seek.  You do not need the next statement to convert this numeric value into a character.  Just add the numeric value to a byte array or list.

Then use the numeric value pairs to paint on a canvas, using a series of .LineTo() and .MoveTo() methods.
References and Tutorials:
http://www.ibrtses.com/delphi/graphicedit1.html
http://www.functionx.com/delphi/gdi/drawing101.htm
http://delphi.about.com/library/bluc/text/uc052102b.htm

After the painting, you will have a bitmap.

Since Base64 uses more characters than bytes, you will be safe to allocate a byte array the same size as the number of characters.
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 375 total points
ID: 21950139
I used SZCodeBaseX (http://www.szutils.net/download.php?ID=2) to encode and decode a small GIF file. Since it was a GIF, I also needed TGIFImage from Torry's
(http://www.torry.net/vcl/graphics/gif/gifimaged7f.zip)

It also worked on a JPG file.
Now, the base64 code that I got came back different than yours. If you could have posted your exact B64 code, then I could test it.

Do you know what extension the file getting from the PDA is?

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, GIFImage;
 
type
  TForm1 = class(TForm)
    btnEncode: TButton;
    btnDecode: TButton;
    Image1: TImage;
    Memo1: TMemo;
    procedure btnEncodeClick(Sender: TObject);
    procedure btnDecodeClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses SZCodeBaseX;
 
{$R *.dfm}
 
 
procedure TForm1.btnEncodeClick(Sender: TObject);
var
  ss: TStringStream;
  sl: TStringList;
begin
  sl := TStringList.Create;
  ss := TStringStream.Create('');
  try
    SZEncodeBase64('C:\image10.gif', ss);
    Memo1.Lines.Text := ss.DataString;
    ss.Position := 0;
    sl.LoadFromStream(ss);
    sl.SaveToFile( 'C:\DelphiEncode.txt' );
  finally
    sl.Free;
    ss.Free;
  end;
end;
 
procedure TForm1.btnDecodeClick(Sender: TObject);
var
  strm: TFileStream;
  ss: TStringStream;
  sl: TStringList;
  s: string;
  GIF: TGIFimage;
begin
  strm := TFileStream.Create( 'C:\delphi-Decode.gif', fmCreate );
  sl := TStringList.Create;
  ss := TStringStream.Create(s);
  try
    strm.Position := 0;
    sl.LoadFromFile( 'C:\DelphiEncode.txt' );
    s := sl.Text;
    SZDecodeBase64(ss, strm);
  finally
    sl.Free;
    ss.Free;
    strm.Free;
    GIF := TGIFImage.Create;
    try
      GIF.LoadFromFile('C:\delphi-Decode.gif');
      Image1.Picture.Assign(GIF);
    finally
      GIF.Free;
    end;
  end;
end;
 
end.

Open in new window

0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 21968494
Anthony, have you tried this code? Do you have any more input?
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 22221591
It's been over a month, have you tried this, yet? Please accept my answer if it worked for you.
0
 

Author Closing Comment

by:COS_IT_AU
ID: 31501471
Hi Eddie, sorry for the delayed response.... Cheers!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question