问题
I'm trying to convert a Delphi-7 ui to a webinterface. Delphi stores button icons in the property Glyph.Data as a hexadecimal string. For example:
object Btn1: TSpeedButton
Left = -1
Top = -1
Width = 26
Height = 27
Anchors = [akTop, akRight]
Flat = True
Glyph.Data = {
36060000424D3606000000000000360000002800000020000000100000000100
1800000000000006000000000000000000000000000000000000BECACDBECACD
BECACDBECACDBECACDBECACDD9D3E6BAB4E3E8E2E8BECACD9A96DE0000CC0000
CC5E5BD6BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD8D
A2A7BECACDBECACDBECACD8C8C8C8C8C8C8DA2A7BECACDBECACDBECACDBECACD
BECACDBECACDBECACDD9D3E6100FCD0000CC100FCDE8E2E93E3DD20000CC0000
CC0000CCBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD64646464
6464646464BECACD8C8C8C646464646464646464BECACDBECACDBECACDBECACD
BECACDBECACDBECACDBAB4E40000CC0000CC0000CCBAB4E44E4CD60000CC0000
CC100FCDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD64646464
64646464648DA2A78C8C8C646464646464646464BECACDBECACDBECACDBECACD
BECACDBAB4E4D9D3E6E8E2E91F1ECF0000CC2F2ED0BECACDC9C3E54E4CD63E3D
D2AAA5E0BECACDBECACDBECACDBECACDBECACD8DA2A78DA2A7BECACD64646464
6464646464BECACDBECACD8C8C8C8C8C8C8DA2A7BECACDBECACDBECACDBECACD
6D6AD90000CC0000CCBAB4E4BECACDC9C3E5BECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD8DA2A76464646464648DA2A7BECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
3E3DD20000CC0000CC7B78DBBECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD8C8C8C6464646464648DA2A7BECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
AAA5E01F1ECF3E3DD2D9D3E6BECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD8DA2A7646464646464BECACDBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
2F2ED00000CC8B87DDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD646464646464646464BECACDBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
0000CC0000CC3E3DD2BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD646464646464646464BECACDBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
6D6AD93E3DD2AAA5E0BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACD8C8C8C6464648DA2A7BECACDBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
BECACDBECACDBECACDBAB4E4BECACDBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD8C8C8CBECACDBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
BECACDBECACD4E4CD60000CC7B78DBBECACDBECACDBECACDBECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACDBECACDBECACD6464646464648C8C8CBE
CACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
BECACDBECACD4E4CD60000CC7B78DBE8E2E98B87DDC9C3E5BECACDBECACDBECA
CDBECACDBECACDBECACDBECACDBECACDBECACDBECACD6464646464648C8C8CBE
CACD6464648DA2A7BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD
BECACDBECACDE8E2E9BAB4E4BECACD8B87DD0000CC3E3DD2BECACD7B78DB4E4C
D6BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACD8DA2A7BECACD64
6464646464646464BECACD6464646464648C8C8CBECACDBECACDBECACDBECACD
BECACDBECACDBECACDBECACDBECACDD9D3E63E3DD29A96DEBECACD4E4CD60000
CCD9D3E6BECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBECACDBE
CACD6464648C8C8CBECACD6464646464648C8C8CBECACDBECACD}
NumGlyphs = 2
How do I convert this string into a Data URI for HTML? I tried to convert it into a byte array to make a bitmap out of it, but this also fails. I wrote a small C# Helper tool to do the conversation, but I can't get it to run. It throws out an ArgumentException on Image.FromStream(ms).
private void button1_Click(object sender, EventArgs e)
{
byte[] bytes = StringToByteArray(textBox1.Text);
byte[] newBytes = new byte[bytes.Length - 4];
for(var i = 4; i < bytes.Length; i++)
{
newBytes[i - 4] = bytes[i];
}
using (var ms = new MemoryStream(bytes))
{
Image image = Image.FromStream(ms);
pictureBox_originalImage.Image = image;
}
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
Thanks in advance.
回答1:
Perform the following to extract a Windows bitmap from this Delphi form file:
- Read the hex string.
- Convert the hex string to binary (a byte array). If using Delphi you can do this with
HexToBin
from theClasses
unit. If using some other language then you will have to use the appropriate function to convert from hex to binary. - Remove the first 4 bytes from the byte array. These bytes that are removed contain the length of the remaining bytes.
- Save these bytes to a file.
What you have saved is a Windows bitmap file. You'll likely want to convert to a web friendly format such as PNG, but I presume you already have tools to do that.
Finally, you'll need to encode that PNG file as base64 and thus form a data URI. Again, I am presuming that you know how to do that.
In the example you present you can also see the NumGlyphs
property indicates that the glyph contains two images. You might want to split the extracted bitmap into multiple images.
回答2:
Excuse me in advance for my very bad english.
There are two options.
1) working with a file text without blank spaces use a algorithm/function that use readln. I post this approch below
2) I have realized some functions that work perfectly
function HexaBmp(const aSource, aDest: String): Integer; // done function BmpHexa(const aSource, aDest: String): Integer; // work done function Bin2Bin(const aSource, aDest: String): Integer; // work done (binary in binary text) function Txt2Bin(const aSource, aDest: String): Integer; // (binary text in binary) working in progress...
This functions uses this subfunctions...
procedure Reading; begin BlockRead(F1, PFBuf^, SIZEFB, BytesIng) end;
procedure Writing; begin BlockWrite(F2, BLWR, Z, BytesOut) end;
but for copyright reasons don't post this (i dont'understend if i'll be owner of these) Sorry for this... I can't explain more. It's more plus complicated. a sofisticate and robust algorithm is necessary but is very fast.
But don't worry because you can use this my little program below for the scope that use the first approach.
program HexaToBmp;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
const
CHX: array ['0'..'F'] of Byte = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15);
var
FtoW: TextFile;
FtoR: TextFile;
WFile: String; // name of write file
Buff: String; // string buffer of read file
vS: String; // calc string
FNY: Word; // final Y
M: Word; // prior of Y
Y: Word; // in loop while read index
procedure TextSeek(var aFtx: Text; POS: Cardinal);
begin
with TTextRec(aFtx) do
begin
BufPos:= 0;
BufEnd:= 0;
SetFilePointer(Handle, POS, nil, FILE_BEGIN)
end
end;
begin
WFile:= StringReplace(ParamStr(1), ExtractFileExt(ParamStr(1)), 'WF', []) + '.bmp';
AssignFile(FtoR, ParamStr(1));
AssignFile(FtoW, WFile);
vS:= '';
try
Reset(FtoR);
ReWrite(FtoW);
TextSeek(FtoR, 8); // position after the first 8 byte
while not EOF(FtoR) do
begin
Readln(FtoR, Buff);
FNY:= Length(Buff) + 1;
M:= 1;
Y:= 2;
while Y < FNY do
begin
if Buff[Y] = #$A then // new line jump
begin
Write(FtoW, vS); // writing current line
vS:= '';
Y:= Y + 1 // jump correct index
end
else
vS:= vS + Chr(16 * CHX[Buff[M]] + CHX[Buff[Y]]); // calc bin value
M:= Y + 1; // increment the variable values
Y:= M + 1
end
end;
Write(FtoW, vS)
finally
CloseFile(FtoR);
CloseFile(FtoW)
end
end.
`
来源:https://stackoverflow.com/questions/37674282/delphi-7-glyph-data-hex-to-data-uri