继续寻求解答......关于256色位图处理:如何用已取得的卫星云图的二进制位图数据生成一张新位图,并保存输出到磁盘上? ( 积分: 300 )

  • 主题发起人 主题发起人 山东好汉
  • 开始时间 开始时间

山东好汉

Unregistered / Unconfirmed
GUEST, unregistred user!
在机械工业出版社出版的王华、梁志刚、王众编写的《Delphi5编程实例与技巧》中,第190页中,作者讲解了位图文件的结构一般由四个部分组成:1、BITMAPINFOHEADER 2、颜色表 3、BITMAPINFO 4、位图数据;
作者将“二进制卫星云图文件中的位图数据取出来转换成位图文件,并且对云图文件的调色板进行切换,以获得不同的显示效果。”但是书中没有给出如何实现的代码。[:(]
请问:作者是如何用位图结构中第4部分的位图数据(例如:PData^(指向卫星位图的二进制数据内存))生成图片的呢?我是百思不得其解,请知道的大侠不吝赐教:用那个API函数可以生成位图文件呢?麻烦贴一段代码,谢谢!
 
在机械工业出版社出版的王华、梁志刚、王众编写的《Delphi5编程实例与技巧》中,第190页中,作者讲解了位图文件的结构一般由四个部分组成:1、BITMAPINFOHEADER 2、颜色表 3、BITMAPINFO 4、位图数据;
作者将“二进制卫星云图文件中的位图数据取出来转换成位图文件,并且对云图文件的调色板进行切换,以获得不同的显示效果。”但是书中没有给出如何实现的代码。[:(]
请问:作者是如何用位图结构中第4部分的位图数据(例如:PData^(指向卫星位图的二进制数据内存))生成图片的呢?我是百思不得其解,请知道的大侠不吝赐教:用那个API函数可以生成位图文件呢?麻烦贴一段代码,谢谢!
 
卫星云图 都是黑白色的,所以很好区分
 
你要参考有关位图文件格式和位图显示方面的资料。一看就明白了。
 
云图是黑白的,生成bmp图是256色的。256色的位图格式:文件头(54字节)+调色板(1024字节)+数据。知道这些你的问题就简单了,创建一个stream,读写、替换相应的数据就行了。
正规的办法:直接创建tbitmap然后操作
bitmap:=tbitmap.Create ;
bitmap.Width :=100;
bitmap.Height :=100;
bitmap.PixelFormat :=pf8bit;
getmem(lplogpal,sizeof(tlogpalette)+((255)*sizeof(tpaletteentry)));
lplogpal.palVersion :=$0300 ;
lplogpal.palNumEntries :=256;
for x:=0 to 255 do
begin
lplogpal.palPalEntry[x].peRed :=x;
lplogpal.palPalEntry[x].peGreen :=x;
lplogpal.palPalEntry[x].peBlue :=x ;
end;
bitmap.Palette :=createpalette(plogpalette(lplogpal)^);
freemem(lplogpal,sizeof(tlogpalette)+((255)*sizeof(tpaletteentry)));
 
to 啊啊啊啊啊:
你的代码:
bitmap:=tbitmap.Create ;
......
freemem(lplogpal,sizeof(tlogpalette)+((255)*sizeof(tpaletteentry)));

再往下面如何用已经有的二进制位图数据(例如:PData^(指向卫星位图的二进制数据内存))生成一副新图片?
 
看看这个???
将已经得到的位图文件头、信息头、调色板、数据在内存中构建BMP位图
我需要编程浏览一些特殊格式的图片,这些图片的格式同BMP查不多,我的处理方法是将此
文件转为位图格式的临时文件temp.bmp,然后再用Image1.Picture.LoadFromFile(...)。
我知道可以Bitmap:=TBitmap.Create在内存中创建一位图,那么如何将位图文件头、信息
头、调色板、数据传过去呢?这样我就不用每次都生成临时文件那么麻烦了,直接在内存
中构建,然后调用,会方便很多!
如果能在回答的同时附带一个小的演示程序最好,只要将一个BMP文件1.bmp显示出来就行,
但记住,是要分别将BMP文件的文件头、信息头、调色板、数据传过去的方式,不要告诉我
直接Image1.Picture.LoadFromFile(1.bmp)啊!

First,你所要的只是将已有的位图数据内容加上一个头信息,那很简单,利用
TBitmapFileHeader和TBitmapInfoHeader可以很容易填写头信息,然后,用
TMemoryStream,Seek(0,soFromBeginning),先把文件和信息头写进去,然后再
写数据,那就可以LoadFromStream.
Second,将图像画到Bitmap上去,未必要逐点赋值;即便要逐点赋值,也可以做得很
快,可以参考FastBmp的直接内存读写.
抄一段我写的有关的创建设备无关位图(DIB)直接内存读写点信息给你看:
...
const hSection = 0;
type
TFColor = record b,g,r:Byte end;
PFColor =^TFColor;
TLine = array[0..0]of TFColor;
PLine =^TLine;
TPLines = array[0..0]of PLine;
PPLines =^TPLines;
...
var
FFileHeader : TBitmapFileHeader;
FInfoHeader : TBitmapInfoHeader;
FInfo : TBitmapInfo;
FBits : Pointer;

Self.PixelFormat:=pf24bit; //设定你的Bitmap都为24位真彩,统一格式.

//Bitmap 文件头
with FFileHeader do
begin
bfType := $4D42;
bfSize := AWidth*AHeight*3+SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader);
bfReserved1 := 0;
bfReserved2 := 0;
bfOffBits := SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader);
end;

with FInfoHeader do
begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := AWidth;
biHeight := AHeight;
biPlanes := 1;
biBitCount := 24;
biCompression := BI_RGB;
biSizeImage := AWidth * AHeight * 3;
end;
FInfo.bmiHeader:=FInfoHeader;
FMyHandle:=CreateDIBSection(0,
FInfo,
DIB_RGB_COLORS,
FBits,
hSection,
0);
memDC:=GetDC(0);

GetDIBits(memDC,Self.Handle,0,AHeight,FBits,FInfo,DIB_RGB_COLORS);
ReleaseDC(memDC);
最重要是两个API,分别是创建一个内存DIB并给指针FBits分配内存,下一句则是
将该DIB的内容读入FBits所指的内存区域.以后的事就简单了,对每一个点,只要
让一个指针指向所需的内存区域:
GetMem(FPixels,AHeight * SizeOf(PLine)); //你自己定义的一个象素点指针
RowInc := (AWidth * 3 + AWidth mod 4); //每行都是4的整数倍个字节
XPointer := Integer(FBits);
for LoopI:=0 to AHeight - 1 do
begin
FPixels^[LoopI] := Pointer(XPointer);
Inc(XPointer,RowInc{ + AWidth mod 4});
end;
{下面这一段是为了让你可以用BitBlt和StretchBlt等直接对HDC进行图像操作
的API,也就是说可以象操作TCanvas那样进行操作,不过要记得,当所有的图像操作
完以后,要GdiFlush才能让对应的FBits内存刷新,切记切记 }
if FMyhDC<>0 then DeleteDC(FMyhDC);
FMyhDC:=CreateCompatibleDC(0);

SelectObject(FMyhDC,FMyHandle);

有什么地方不懂的话可以去看FastBmp的源码,上面一段基本是照抄,我是用在自己
定义的扩展TBitmap类中的.希望对你有帮助.
对了,想要FastBmp的话我可以mail你.
 
谢谢:app2001
你上面的代码取出DIB的内容读入FBits后,如何用FBits创建出一副新位图并且输出保存到磁盘上?
 
这个资料也是我从大富翁上弄来的,关于别人的讨论,那些资料我可没有啊
 
我找到一篇笔记似乎有些靠谱,你看看
http://www.delphibbs.com/keylife/iblog_show.asp?xid=11971
KeyLife富翁笔记
作者?: zgl198171
标题?: Delphi中如何编写图像解析组件
 
奇怪,我以前用类似代码就不行,楼主说的那个东西其实就是一个数组,但是我没有试成功过,

是利用BITMAPINFO结构,你说的那个pData也是它的一个成员,这个结构好象在windows单元里面

下面转贴一个VC的代码

http://www.ccw.com.cn/htm/produ/special/vc/neimu/01_9_17_40.asp

// MyBmp.h: interface for the MyBmp class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)
#define AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define FALSERETURN {_lclose(hFile);return 0;}
#define IMAGECOLORS(x,y) (1<<((x)*(y)))
//单行BMP数据的字节数
#define DWORD_WBYTES(x) ((((x)+31UL)>>5)<<2)

#define min(a, b) (((a) < (b)) ? (a) : (b))

#ifdef WIN32
#define BMPDATA BYTE
#else
#define BMPDATA BYTE _huge
#endif
// #include &quot;test.cpp&quot;

#define PALVERSION 0x0300
#define DIB_STORAGEWIDTH(x) ((x + 3) &amp; ~3)
#define WIDTHBYTES(i) ((i+31)/32*4)
#define MAXPALETTE 256 /* max. # supported palette entries */
#define MAXLOADFLCNUMBER 255

class PALETTE
{
private:
HPALETTE hOldPal;
protected:
HPALETTE hPal;

public:
PALETTE(){memset(this,0,sizeof(PALETTE));}
~PALETTE(){if(hPal)DeleteObject(hPal);};
HPALETTE CreatePal(BITMAPINFO*);
HPALETTE CreatePal(LPLOGPALETTE Pal);
HPALETTE GetPal(){return hPal;}
UINT SetPal(HDC);
void ResetPal(HDC);

};


class MYDIB : public PALETTE
{

protected:
HGLOBAL hData;
struct
{
BITMAPINFOHEADER b;
RGBQUAD r[256];
}p;

public:
LPBITMAPINFO lpInfo;
LPBITMAPINFOHEADER lpInfoHead;

MYDIB();
~MYDIB();
int Show(HDC,int,int,int,int,int,int,int,int,DWORD);
inline int Show(HDC hDC,int x1,int y1,int x2,int y2,
int x3,int y3,int x4,int y4)
{ return Show(hDC,x1,y1,x2,y2,x3,y3,x4,y4,SRCCOPY);}
inline int Show(HDC hDC,int x,int y)
{ return Show(hDC,x,y,0,0,0,0,0,0,SRCCOPY);}
inline int Show(HDC hDC)
{ return Show(hDC,0,0,0,0,0,0,0,0,SRCCOPY);}

Show(MYDIB*,int,int,int,int,int,int,BYTE,BYTE,BYTE,
BYTE,BYTE,BYTE);
Show(MYDIB*,int,int,int,int,int,int,register
BYTE,register BYTE);

};

class BMP : public MYDIB
{

public:
int Open(LPCSTR,int);
int inline Open(LPCSTR name){return Open(name,0);}
};

#endif // !defined(AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)

// MyBmp.cpp: implementation of the MyBmp class.
//
//////////////////////////////////////////////////////////////////////

#include &quot;stdafx.h&quot;
#include &quot;MyBmp.h&quot;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//class PALETTE
//////////////////////////////////////////////////////////////////////

UINT PALETTE::SetPal(HDC hDC)
{
if(hPal)
{
SelectPalette(hDC,hPal,0);
return RealizePalette(hDC);
}
else return FALSE;
}

void PALETTE::ResetPal(HDC hDC)
{
if(hOldPal)
{
SelectPalette(hDC,hOldPal,0);
hOldPal=0;
}
}

HPALETTE PALETTE::CreatePal(LPLOGPALETTE Pal)
{
if(hPal)DeleteObject(hPal);
if(Pal_>palNumEntries<=256)hPal=CreatePalette(Pal);
return hPal;
}

//////////////////////////////////////////////////////////////////////
//class DIBPALETTE
//////////////////////////////////////////////////////////////////////

HPALETTE PALETTE::CreatePal(BITMAPINFO* info)
{

struct
{
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[256];
} p;
LPLOGPALETTE Pal=(LPLOGPALETTE)&amp;p;

Pal_>palVersion=0x300;
Pal_>palNumEntries=
/*min*/((WORD)IMAGECOLORS(info_>bmiHeader.biBitCount,1));//,info_>bmiHeader.biClrUsed);

for(int i=0;i<Pal_>palNumEntries;i++)
{
Pal_>palPalEntry.peRed=info_>bmiColors.rgbRed;
Pal_>palPalEntry.peGreen=
info_>bmiColors.rgbGreen;
Pal_>palPalEntry.peBlue=info_>bmiColors.rgbBlue;
Pal_>palPalEntry.peFlags =PC_NOCOLLAPSE;
}

return PALETTE::CreatePal(Pal);
}

//////////////////////////////////////////////////////////////////////
// MYDIB Class
//////////////////////////////////////////////////////////////////////

MYDIB::MYDIB()
{
memset(this,0,sizeof(BMP));
lpInfo=(LPBITMAPINFO)&amp;p;
lpInfoHead=(LPBITMAPINFOHEADER)&amp;p;
}

MYDIB::~MYDIB()
{
if(hData)GlobalFree(hData);
}

int MYDIB::Show(HDC hDC,int x1,int y1,int x2,int y2,int x3,
int y3,int x4,int y4,DWORD Rop)
{
if(x2<=0)x2=(int)lpInfoHead_>biWidth+x2;
if(y2<=0)y2=(int)lpInfoHead_>biHeight+y2;
if(x4<=0)x4=(int)lpInfoHead_>biWidth+x4;
if(y4<=0)y4=(int)lpInfoHead_>biHeight+y4;
// if(w_hp)SetPalette(hDC);
BMPDATA* Data=(BMPDATA*)GlobalLock(hData);
// int i=StretchDIBits(hDC,x1,y1,x2,y2,x3,y3,x4,y4,
Data,Info,DIB_RGB_COLORS,Rop);
int i=StretchDIBits(hDC,x1,y1,x2,y2,x3,
(int)lpInfoHead_>biHeight_y3_y4,x4,y4,Data,lpInfo,
DIB_RGB_COLORS,Rop);
GlobalUnlock(hData);
return i;
}

int MYDIB::Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,int y3,
BYTE r1,BYTE g1,BYTE b1,BYTE r2,BYTE g2,BYTE b2)
{
register DWORD c1=(((DWORD)r1)<<16)+(((DWORD)g1)<<8)+b1;
register DWORD c2=(((DWORD)r2)<<16)+(((DWORD)g2)<<8)+b2;
register DWORD c;
register DWORD *rq=(DWORD*)p.r;
if(!dib_>hData)
{
memcpy(dib,this,sizeof(MYDIB));
dib_>lpInfo=(LPBITMAPINFO)&amp;(dib_>p);
dib_>lpInfoHead=(LPBITMAPINFOHEADER)&amp;(dib_>p);
dib_>lpInfoHead_>biWidth =x2+x1;
dib_>lpInfoHead_>biHeight =y2+y1;
DWORD Size=dib_>lpInfoHead_>biWidth
*dib_>lpInfoHead_>biHeight
*IMAGECOLORS(dib_>lpInfoHead_>biBitCount,1)/8;
dib_>hData=GlobalAlloc(GMEM_FIXED,Size);
}

x2=min(x2,(int)dib_>lpInfoHead_>biWidth _x1);
y2=min(y2,(int)dib_>lpInfoHead_>biHeight_y1);

BMPDATA *Data1=(BMPDATA*)GlobalLock(hData);
BMPDATA *Data2=(BMPDATA*)GlobalLock(dib_>hData);
DWORD w1=DWORD_WBYTES(lpInfoHead_>biWidth
*lpInfoHead_>biBitCount);
DWORD w2=DWORD_WBYTES(dib_>lpInfoHead_>biWidth
*dib_>lpInfoHead_>biBitCount);
Data1+=(w1*(lpInfoHead_>biHeight_y3_y2)
+x3*lpInfoHead_>biBitCount/8);
Data2+=(w2*(dib_>lpInfoHead_>biHeight_y1_y2)
+x1*dib_>lpInfoHead_>biBitCount/8);
for(int j=0;j<y2;j++)
{
for(register int i=0;i<x2;i++)
{
c=*(rq+*(Data1+i));
if( (c<c1)|| (c>c2)||((WORD)c<(WORD)c1)
|| ((WORD)c>(WORD)c2)
|| ((BYTE)c<(BYTE)c1)
||((BYTE)c>(BYTE)c2)) *(Data2+i)=*(Data1+i);
}
Data1+=w1;
Data2+=w2;
}

GlobalUnlock(hData);
GlobalUnlock(dib_>hData);
return TRUE;
}

int MYDIB::Show(MYDIB* dib,int x1,int y1,int x2,int y2,int x3,
int y3,register BYTE x,register BYTE y)
{
register BMPDATA d;

if(!dib_>hData)
{
memcpy(dib,this,sizeof(MYDIB));
dib_>lpInfo=(LPBITMAPINFO)&amp;(dib_>p);
dib_>lpInfoHead=(LPBITMAPINFOHEADER)&amp;(dib_>p);
dib_>lpInfoHead_>biWidth =x2+x1;
dib_>lpInfoHead_>biHeight =y2+y1;
DWORD Size=(dib_>lpInfoHead_>biWidth+1)
*dib_>lpInfoHead_>biHeight
*dib_>lpInfoHead_>biBitCount/8;
//IMAGECOLORS(dib_>lpInfoHead_>biBitCount,1)/8;
dib_>hData=GlobalAlloc(GMEM_FIXED,Size);
}

x2=min(x2,(int)dib_>lpInfoHead_>biWidth _x1);
y2=min(y2,(int)dib_>lpInfoHead_>biHeight_y1);
BMPDATA *Data1=(BMPDATA*)GlobalLock(hData);
BMPDATA *Data2=(BMPDATA*)GlobalLock(dib_>hData);
DWORD w1=DWORD_WBYTES(lpInfoHead_>biWidth
*lpInfoHead_>biBitCount);
DWORD w2=DWORD_WBYTES(dib_>lpInfoHead_>biWidth
*dib_>lpInfoHead_>biBitCount);
Data1+=(w1*(lpInfoHead_>biHeight_y3_y2)
+x3*lpInfoHead_>biBitCount/8);
Data2+=(w2*(dib_>lpInfoHead_>biHeight_y1_y2)
+x1*dib_>lpInfoHead_>biBitCount/8);

for(int j=0;j<y2;j++)
{
for(register int i=0;i<x2;i++)
{
d=*(Data1+i);
if((d<x)||(d>y))*(Data2+i)=d;
}
Data1+=w1;
Data2+=w2;
}

GlobalUnlock(hData);
GlobalUnlock(dib_>hData);
return TRUE;
}

//////////////////////////////////////////////////////////////////////
//class bmp
//////////////////////////////////////////////////////////////////////

int BMP::Open(LPCSTR File,int sty) //sty: 0:enable hpal 1:disnnable hpal
{
BITMAPFILEHEADER FileHead;
int i;//,j,k;
HFILE hFile;
DWORD uBytes;
DWORD Size;

hFile=_lopen(File,OF_READ);
if(hFile==HFILE_ERROR)return 0;

//读取文件头
i=_lread(hFile,&amp;FileHead,sizeof(BITMAPFILEHEADER));
if(i==HFILE_ERROR) FALSERETURN;//goto BMP_FALSE_END;
// Type=FileHead.bfType;

//读取信息头
i=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
_lread(hFile,lpInfoHead,i);

//建立调色板
if(!sty)CreatePal(lpInfo);

uBytes=_llseek(hFile,0,2);
if ((FileHead.bfSize)>uBytes) FALSERETURN;//goto BMP_FALSE_END;


if(hData)GlobalFree(hData);
Size=uBytes_FileHead.bfOffBits;
hData=GlobalAlloc(GMEM_FIXED,Size);
BMPDATA * Data=(BMPDATA*)GlobalLock(hData);

//读取数据
_llseek(hFile,FileHead.bfOffBits,0);

for(;_lread(hFile,Data,RBLOCK)==RBLOCK;Data+=RBLOCK);
GlobalUnlock(hData);
_lclose(hFile);
return TRUE;
}
 
先根据云图大小设置bitmap长宽,然后指定调色板,最后从云图文件一行一行的把数据写入bitmap就行了,用scanline也行,用我最开始说的stream写也行
 
先了解下 BMP 的结构
颜色好象是 RGB 吧?
一个像素占 6 个字节大小~
 
To 啊啊啊啊啊:
怎样才能把stream中的数据流写入bitmap呢[?]
 
他的意思可能是是TBitmap.LoadFromStream,但是楼主只有bits的数据,所以我还是认为比较好的做法是采用CreateDIBSection的方式,记得有一个bitmap的结构里面有个

tagBITMAP = packed record
bmType: Longint;
bmWidth: Longint;
bmHeight: Longint;
bmWidthBytes: Longint;
bmPlanes: Word;
bmBitsPixel: Word;
bmBits: Pointer;// 这个东西就是楼主要放的东西
end;

能把这个结构填出来就可以了,然后显示到界面,我没试成功,但是以前看过类似的VC代码,楼主可以考虑一下
 
To chenybin:
你说得对呀!我也能取出: bmBits: Pointer;位图的数据,填充好:tagBITMAP = packed record记录,
但是就是不知道如何传送给bitmap中,我想这样就可以利用bitmap.SaveToFile();方法保存输出图片了!
 
其中m_Bitmap就是那个结构,以前公司的代码,不便多说,关键是蓝色部分

void xxx::Draw(CDC * pDC, RECT ClientRect, FRect MRect, double dScale)
{
RECT Rect;
……

this->Draw(m_pDispBuf, ClientRect, Rect, dScale);

CDC * pBitmapDC = new CDC;
[blue]pBitmapDC->CreateCompatibleDC(pDC);[/blue]

CBitmap * pMapBitmap = new CBitmap;
[blue]pMapBitmap->CreateBitmapIndirect(&amp;m_Bitmap);[/blue]

CBitmap * pOldBitmap = pBitmapDC->SelectObject(pMapBitmap);
[blue]pDC->BitBlt(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, pBitmapDC, 0, 0, SRCCOPY);[/blue]
pBitmapDC->SelectObject(pOldBitmap);
pMapBitmap->DeleteObject();
delete pMapBitmap;
delete pBitmapDC;
}
 
To chenybin:
下面是《Delphi Win32核心API参考》中的代码,和你的代码很相象!
这个代码如何保存输出图像呢?
unit BitmapIndirectU;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
PaintBox1: TPaintBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{Note: This example works correctly only under a 256 color video driver}

procedure TForm1.Button1Click(Sender: TObject);
var
TheBitmap: HBITMAP; // a handle to the new bitmap
BitmapInfo: Windows.TBitmap; // the bitmap information structure
OffscreenDC: HDC; // a handle to a memory device context
BitmapBits: array[0..4095] of byte; // holds the bitmap image
begin
{initialize the bitmap image to the color in palette slot 5}
FillMemory(@BitmapBits, 4096, 5);

{define the new bitmap}
BitmapInfo.bmType := 0;
BitmapInfo.bmWidth := 64;
BitmapInfo.bmHeight := 64;
BitmapInfo.bmWidthBytes := 64;
BitmapInfo.bmPlanes := 1;
BitmapInfo.bmBitsPixel := 8; // 8 bits/pixel, a 256 color bitmap
BitmapInfo.bmBits := @BitmapBits;

{create the bitmap based on the bitmap information}
TheBitmap := CreateBitmapIndirect(BitmapInfo);

{create a memory device context compatible with the screen}
OffscreenDC := CreateCompatibleDC(0);

{select the new bitmap and a stock pen into the memory device context}
SelectObject(OffscreenDC, TheBitmap);
SelectObject(OffscreenDC, GetStockObject(WHITE_PEN));

{draw a single line on the bitmap}
MoveToEx(OffscreenDC, 0, 0, nil);
LineTo(OffscreenDC, 64, 64);

{display the bitmap}
BitBlt(PaintBox1.Canvas.Handle, (PaintBox1.Width div 2)-32,
(PaintBox1.Height div 2)-32, 64, 64, OffscreenDC, 0, 0, SRCCOPY);

{we are done with the memory device context and bitmap, so delete them}
DeleteDC(OffscreenDC);
DeleteObject(TheBitmap);
end;

end.
 
BitBlt(PaintBox1.Canvas.Handle, (PaintBox1.Width div 2)-32,
(PaintBox1.Height div 2)-32, 64, 64, OffscreenDC, 0, 0, SRCCOPY);

把PaintBox1修改成Image1,然后用Image1.Bitmap.SaveFile,

如果不行采用在内存里面建立TBitmap的方法,然后用CopyRect把PaintBox1的东西拷贝到内存的TBitmap里面,然后用TBitmap的SaveToFile的方法,这个代码就很多了

CopyRect(目标区域,源Canvas,源区域)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
930
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部