奇怪的问题探讨:BMP的读写和恢复问题
如下是我要实现的问题:
1. 我想把一张BMP图片,保存为UnicodeString
2. 然后在UnicodeString中恢复为BMP图片
得到妖哥指点:序列化。将位图的每一个字节用十六进制来表示,最后拼成一个字符串。还原的时候,从字符串每次取两个字符,转化成对应的byte。
我是这样实现并测试的:
TBitmap *bmp = new TBitmap();
TImage *Img = new TImage(this);
TColor color;
int GValue;
int BValue;
int RValue;
UnicodeString uStr = "";
bmp->LoadFromFile("d:\\test.bmp");
Img->Width = bmp->Width;
Img->Height= bmp->Height;
Img->Canvas->CopyRect(Rect(0,0,Img->Width,Img->Height) , bmp->Canvas,Rect(0,0,Img->Width,Img->Height));
for(int y = 0 ; y < Img->Height ; y++)
{
for(int x = 0; x < Img->Width; x++)
{
color = Img->Canvas->Pixels[y][x];
BValue = GetBValue(color) ;
GValue = GetGValue(color) ;
RValue = GetRValue(color) ;
uStr += IntToHex(RValue,2) ;
uStr += IntToHex(GValue,2) ;
uStr += IntToHex(BValue,2) ;
}
}
//-------恢复数据-------------------------------------------
UnicodeString hex_val="";
UnicodeString s1 = "0x";
UnicodeString s2 = "";
TImage *fbmp = new TImage(this);
fbmp->Width = bmp->Width;
fbmp->Height= bmp->Height;
fbmp->Canvas->Brush->Color = clBlack;
fbmp->Canvas->Rectangle(0,0,fbmp->Width,fbmp->Height);
int index = 1 ;
for(int x = 0 ; x < fbmp->Height ; x++)
{
for(int y = 0; y < fbmp->Width; y++)
{
s2 = uStr.SubString(index,2);
hex_val = s1 + s2;
RValue= hex_val.ToInt();
index+=2;
s2 = uStr.SubString(index,2);
hex_val = s1 + s2;
GValue= hex_val.ToInt();
index+=2;
s2 = uStr.SubString(index,2);
hex_val = s1 + s2;
BValue= hex_val.ToInt();
index+=2;
fbmp->Canvas->Pixels[x][y]= RGB(RValue, GValue, BValue);
}
}
fbmp->Picture->Bitmap->SaveToFile("d:\\testback.bmp");
#include <stdio.h>
#include <tchar.h>
BOOL __fastcall CrnBitmpaToString(Graphics::TBitmap *bmp, String &strText)
{
BOOL bResult = FALSE;
TMemoryStream *ms = new TMemoryStream();
try
{
bmp->SaveToStream(ms);
ms->Position = 0;
TCHAR sz[3] = { 0x0 };
for (int i = 0; i < ms->Size; i++)
{
_stprintf(sz, "%02X", ((LPBYTE)ms->Memory)[i]);
strText += sz;
}
bResult = TRUE;
}
__finally
{
delete ms;
}
return bResult;
}
BOOL __fastcall CrnStringToBitmap(String strText, Graphics::TBitmap *bmp)
{
BOOL bResult = FALSE;
TMemoryStream *ms = new TMemoryStream();
try
{
int nSize = strText.Length() / 2;
ms->SetSize(nSize);
int p = 1;
DWORD dw;
TCHAR sz[3] = { 0x0 };
for (int i = 0; i < nSize; i++)
{
sz[0] = strText[p++];
sz[1] = strText[p++];
dw = 0;
_stscanf(sz, TEXT("%2X"), &dw);
((LPBYTE)ms->Memory)[i] = (BYTE)dw;
if (p >= strText.Length()) break;
}
ms->Position = 0;
bmp->LoadFromStream(ms);
bResult = TRUE;
}
__finally
{
delete ms;
}
return bResult;
}
// ---------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap;
bmp->LoadFromFile("D:\\ccrun\\123.bmp");
String strText;
CrnBitmpaToString(bmp, strText);
TStringList *lst = new TStringList;
lst->Text = strText;
lst->SaveToFile("D:\\ccrun\\123.dat");
delete lst;
delete bmp;
}
// ---------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap;
TStringList *lst = new TStringList;
lst->LoadFromFile("D:\\ccrun\\123.dat");
CrnStringToBitmap(lst->Text, bmp);
delete lst;
bmp->SaveToFile("D:\\ccrun\\234.bmp");
delete bmp;
}