如何把一个数据文件的内容显示为位图?(100分)

  • 主题发起人 主题发起人 peacelover
  • 开始时间 开始时间
P

peacelover

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在做雷达数据仿真,这些数据经过处理后又得到一个数据文件,它里面的各个数据代表各个点反射回的信号幅度大小,请问如何把这些数据映射为位图上各个点的RGB值?
 
说清楚一点? 你的"点"和RGB有什么关系?
 
数据文件中,一个目标会有坐标吗?
在屏幕上相应的点中标出来不就是了,另外,RGB只是颜色值。
 
可不可以只用灰度来显示,
因为rgb指red,green,blue三色的和,你如果只是想用
颜色区别每一点的信号幅度大小,可以把三色中的一色
的大小按色度=f(信号幅度)来对应,其他两色不变。当然
你也可以把三种色度大小按同样的色度=f(信号幅度)来对应
这要看你的习惯。
具体在delphi中的应用可参照以下delphi中的说明:
f you specify TColor as a specific 4-byte
hexadecimal number instead of using the
constants defined in the Graphics unit, the
low three bytes represent RGB color intensities
for blue, green, and red, respectively.
The value $00FF0000 represents full-intensity,
pure blue, $0000FF00 is pure green, and $000000FF
is pure red. $00000000 is black and $00FFFFFF is white.

If the highest-order byte is zero ($00), the color obtained
is the closest matching color in the system palette. If the
highest-order byte is one ($01), the color obtained is the
closest matching color in the currently realized palette. If
the highest-order byte is two ($02), the value is matched with
the nearest color in the logical palette of the current device
context.
 
JPEG 6a里面有一个rdppm.c可以读PPM/PGM格式的文件。
类似的源代码还是很多的,用搜索引擎上网找一下就可以
发现一大堆。<a href="http://infoseek.go.com">infoseek.go.com</a>是比较好的搜索引擎。
/*
* rdppm.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to read input images in PPM/PGM format.
* The extended 2-byte-per-sample raw PPM/PGM formats are supported.
* The PBMPLUS library is NOT required to compile this software
* (but it is highly useful as a set of PPM image manipulation programs).
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; start_input may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed PPM format).
*/
 
//---------------------------------------------------------------------------
void *ExpandLine(void *data,int w,int h,int bytespp=1)
{
int linebytes = w*bytespp;
int linew = (linebytes+3)&amp;(~3);

char *buf = DoAlloc(linew*h);

for(int i=0;i<h;i++)
{
memcpy(buf+linew*i,((char*)data)+linebytes*i,linebytes);
}
return buf;
}
//---------------------------------------------------------------------------
struct TGrayBMPHeader
{
BITMAPINFOHEADER header;
RGBQUAD pals[256];

TGrayBMPHeader();

void SetInfo(int w,int h)
{
header.biWidth = w;
header.biHeight = -h;
}
};
//---------------------------------------------------------------------------
TGrayBMPHeader::TGrayBMPHeader()
{
header.biSize = sizeof(header);
header.biPlanes = 1;
header.biBitCount = 8;
header.biCompression = BI_RGB;
header.biSizeImage = 0;
header.biXPelsPerMeter = 120;
header.biYPelsPerMeter = 120;
header.biClrUsed = 0;
header.biClrImportant = 0;

for(int i=0;i<256;i++)
{
pals.rgbBlue = (unsigned char)i;
pals.rgbGreen = (unsigned char)i;
pals.rgbRed = (unsigned char)i;
pals.rgbReserved = 0;
}
}
//---------------------------------------------------------------------------
HBITMAP CreateBMP(void *y,int w,int h)
{
assert(y);

void *ty = NULL;

if(w&amp;3) //测试4字节对齐
{
ty = ExpandLine(y,w,h,1);
}

TGrayBMPHeader header;
header.SetInfo(w,h);

HDC dc = GetDC(0);
assert(dc);

HBITMAP handle = CreateDIBitmap(
dc,&amp;(header.header),CBM_INIT,(ty?ty:y),(BITMAPINFO *)(&amp;header),DIB_RGB_COLORS);

ReleaseDC(0,dc);

if(ty)
DoFree(ty);

return handle;
}
//---------------------------------------------------------------------------
 
系统出什么问题了??
程序贴不出来,下面是gray.uue,粘贴到一个
文本文件,然后改名为gray.uue,用WINZIP打开就可以了.


_=_
_=_ Part 001 of 001 of file gray.zip
_=_

begin 666 gray.zip
M4$L#!!0````(`,R(/BA3%0-$N@(``+<'```(````9W)A>2YC<'"U54UOVD`0
MO4?*?]@36H,3/M%656A484/`$@1*$C55%:'%'O!*QD;K)=2MZ(_JH;=>>^@Y
M:J4>>^V?Z*QM;'"0VDK)'H"=?3/[YNW,4*WN/=S:W;D-N$/*S7<SYCL=[@--
M#`Z33.>^)(OXT]5V=S[L[A!<:NLA<!1)",DI6=0V[0NU03O-0)5CK40_'FL(
M3*"VRP0IC^9CA+6/8,2/NN<%-FUUF]WAF77=;.AQI+*;^XP#0=45_/2@QE^X
M-5ZI:,E)RDNM*4SM640Q<B4)P'5*U6UE326D53).>)+]UM(,ELF7`#D7/L$@
M:$=;]6$%#Z68VY)<M@2+C&amp;Z_#<P!D:EK6)?=>M/Z/^NUF_5&amp;<T#<^#QE.&amp;@9
MKZ[J#9*M&amp;?/"MT=/G]UD.FW&amp;I;F`/;M>@+3/<4`W7[:@8G+E_HB_YHYTR=H;
M;YRV@4]<B:=[;B[@LO;@@FUF=')2S##3+F-VP=]#KM$I"7$?C&amp;EROGKM#-WW
MF(^5G*$/BP"#2S.8HU8IX'D18`;3F8`PY($?`PQKB"]51"E6UI1-(`US4`1<
M]/$+^R"Z($$H(D?W(&amp;_^#C$]<16"DZ6S#6!-9X&amp;03*64`+;U&amp;);5]BZ+BX[?
M[(O)R/#FJW3HW`_YQ,>;5<-IO+;5H24`_/]Q&amp;*Q2^7>'$,0M@O+4EX_1Q^VD
M58DI@$G`>DPG9[1];+(0:4D:%1JR+",D>G[5Z61V/J:+TK%&amp;2+7ZZ=>WNR<_
MOG_Y^?GNZ^][[Q"[KDWN2%_HKGZX-LZVC83-B9)6Q6HN8("<8+MA$L=6,QID
MPZ0'J/!I*HZ]!DW%<)&amp;+!^B2J-*PL'>F;$9STHZME]).W$/;4C>-[M`ZMRYU
M*J.7,CJ)-)WF@Y"4-5I:03&amp;BZJVAV>OT!A<Y@0%XP$)0-/5U8BBFC+3/^N3O
MY@RK4-DS6#KS$_JUQRB7/U!+`0(4`!0````(`,R(/BA3%0-$N@(``+<'```(
M``````````$`(`"V@0````!G<F%Y+F-P<%!+!08``````0`!`#8```#@`@``
"````
`
end
 
实在抱歉,上一篇发错位置了:(
既然如此,就说一说吧。

一般来说,图象数据是用二维矩阵表示的,每个象素是二维矩阵
的一个元素。而能显示的图象,应该是每个象素的值都在0~255
之间。在图象处理中,经常会将图象处理为其它范围,所以,显
示时第一步就是将图象数据规一化到0~255。这个规一化可以是
线性的( (val-min)*255/(max-min) ),也可以是非线性的,
如先取log。使用何种规一化函数就看实际数据了。如果变化范围
相当大,则取log等非线性规一化比较好,否则线性规一化效果好。

规一化之后的数据要存放在BYTE类型的二维矩阵中,只有这种二维
矩阵才可以被显示出来。另外,由于WIN32GDI在处理数据时要求图
象每行的字节宽度为4的整数倍,所以,如果原始数据的宽度不适合
的化,要注意先将行调整到合适的宽度。

然后就是用这个二维矩阵创建一个HBITMAP的句柄了。上面的方法
转换出来的是灰度图象,所以还要为其生成一个调色板。

下面是我用来画图的函数:
//---------------------------------------------------------------------------
//辅助函数:如果图象的宽度不是4的倍数,则将其对齐到4的倍数
//输入参数data为BYTE型的图象,宽度w,高度h
//返回的缓冲区内存放了对齐后的图象。注意,在NT4上面,用
//new分配的内存和用GlobalAlloc分配的内存是有区别的!!
//如果较大的图象存放在用new分配的内存中,则系统显示不出来,但
//不会返回任何错误信息!!
void *ExpandLine(void *data,int w,int h)
{
int linebytes = w;
int linew = (linebytes+3)&amp;(~3);

char *buf = GlobalAlloc(GMEM_FIXED,linew*h);

for(int i=0;i&amp;lt;h;i++)
{
memcpy(buf+linew*i,((char*)data)+linebytes*i,linebytes);
}
return buf;
}
//---------------------------------------------------------------------------
//这个结构由于创建HBITMAP,其pals成员就是调色板
struct TGrayBMPHeader
{
BITMAPINFOHEADER header;
RGBQUAD pals[256];

TGrayBMPHeader();

void SetInfo(int w,int h)
{
header.biWidth = w;
header.biHeight = -h;
}
};
//---------------------------------------------------------------------------
TGrayBMPHeader::TGrayBMPHeader()
{
header.biSize = sizeof(header);
header.biPlanes = 1;
header.biBitCount = 8;
header.biCompression = BI_RGB;
header.biSizeImage = 0;
header.biXPelsPerMeter = 120;
header.biYPelsPerMeter = 120;
header.biClrUsed = 0;
header.biClrImportant = 0;

for(int i=0;i<256;i++)
{
pals.rgbBlue = (unsigned char)i;
pals.rgbGreen = (unsigned char)i;
pals.rgbRed = (unsigned char)i;
pals.rgbReserved = 0;
}
}
//---------------------------------------------------------------------------
//真正的函数在这里,data是BYTE型图象,宽度w,高度h
//返回的句柄可以用其它WIN32函数显示,但记得释放哦:)
HBITMAP CreateBMP(void *y,int w,int h)
{
assert(y);

void *ty = NULL;

if(w&amp;3) //测试4字节对齐
{
ty = ExpandLine(y,w,h,1);
}

TGrayBMPHeader header;
header.SetInfo(w,h);

HDC dc = GetDC(0);//该死的GDI总是要一个DC,虽然创建HBITMAP可以与DC无关。这个DC比较适合于显示,如果想打印的化,应该用别的DC。
assert(dc);

HBITMAP handle = CreateDIBitmap(
dc,&amp;(header.header),CBM_INIT,(ty?ty:y),(BITMAPINFO *)(&amp;header),DIB_RGB_COLORS);

ReleaseDC(0,dc);

if(ty)
GlobalFree(ty);

return handle;
}
//---------------------------------------------------------------------------
 
接受答案了.
 
后退
顶部