我招谁惹谁了!!!???快一周了,问了很多人,都没能说清楚,哪位大虾能帮我看看???(100分)

  • 主题发起人 主题发起人 cqbaobao
  • 开始时间 开始时间
C

cqbaobao

Unregistered / Unconfirmed
GUEST, unregistred user!
我用Image控件调入一个位图,进行了一些处理,
处理中设置了位图的PixelFormat属性,将其从pf24bit设为pf8bit,
并对位图内容进行了修改,(但未修改原始位图)
第一次运行正常,

重新装入原始位图后,再进行相同的操作(操作步骤完全一样),竟然结果与上一次不相同,

我实在是不知道怎么回事?
 
你的代码呢?
让大家看看啊。
 
先把代码拿出来,大家会帮你解决问题的。
 
对,图像问题找卷大侠没错。
 
// 种子填充,从VC资料中翻译过来
procedure Zztc(bmp: TBitmap; w, h, x, y: integer);
// bmp: 为要处理的位图
// w, h: 位图的宽度、高度
// x, y: 初始种子点
type
TSeed = record
Left: integer;
Top : integer;
end;
ASeed = array of TSeed; // 用来模拟堆栈
const
tempCol = 10; // 临时颜色变量,填充后
var
xCurrent, yCurrent, // 当前要处理的点坐标
StackPoint: integer; // 指向堆栈顶的指针
Seeds: ASeed;
colCurrent: Byte; // 当前点颜色
pCurrent: PByteArray;
begin
// 这里是关键,bmp 只有黑白两色,
// bmp 是24位图,但为了后面处理方便,用以下方法改为 8 位色图
if bmp.PixelFormat <> pf8bit then
bmp.PixelFormat := pf8bit;
// 就出了以上问题

SetLength(Seeds, w * h);
Seeds[0].Left := x; // 初始化
Seeds[0].Top := y;
StackPoint := 1;

while StackPoint <> 0 do
begin
xCurrent := Seeds[StackPoint - 1].Left;
yCurrent := Seeds[StackPoint - 1].Top;
dec(StackPoint);

pCurrent := bmp.ScanLine[yCurrent];

// 当前点标记为临时颜色
pCurrent[xCurrent] := tempCol;

// 判断左面的点
if xCurrent > 0 then
begin
pCurrent := bmp.ScanLine[yCurrent];
colCurrent := pCurrent[xCurrent - 1];
if (colCurrent <> 0) and (colCurrent <> tempCol) then
begin
inc(StackPoint);
Seeds[StackPoint - 1].Left := xCurrent - 1;
Seeds[StackPoint - 1].Top := yCurrent;
end;
end;

// 判断下面的点
if yCurrent < h - 1 then
begin
pCurrent := bmp.ScanLine[yCurrent + 1];
colCurrent := pCurrent[xCurrent];
if (colCurrent <> 0) and (colCurrent <> tempCol) then
begin
inc(StackPoint);
Seeds[StackPoint - 1].Left := xCurrent;
Seeds[StackPoint - 1].Top := yCurrent + 1;
end;
end;

// 判断右面的点
if xCurrent < w - 1 then
begin
pCurrent := bmp.ScanLine[yCurrent];
colCurrent := pCurrent[xCurrent + 1];
if (colCurrent <> 0) and (colCurrent <> tempCol) then
begin
inc(StackPoint);
Seeds[StackPoint - 1].Left := xCurrent + 1;
Seeds[StackPoint - 1].Top := yCurrent;
end;
end;

// 判断上面的点
if yCurrent > 0 then
begin
pCurrent := bmp.ScanLine[yCurrent - 1];
colCurrent := pCurrent[xCurrent];
if (colCurrent <> 0) and (colCurrent <> tempCol) then
begin
inc(StackPoint);
Seeds[StackPoint - 1].Left := xCurrent;
Seeds[StackPoint - 1].Top := yCurrent - 1;
end;
end;
end;

Seeds := nil;

// 将以上填充了临时颜色的点以外的所有点填充成黑色,为了填满黑色区域内的空洞
for yCurrent := 0 to h - 1 do
begin
pCurrent := bmp.ScanLine[yCurrent];
for xCurrent := 0 to w - 1 do
begin
if pCurrent[xCurrent] = tempCol then
pCurrent[xCurrent] := 19
else
pCurrent[xCurrent] := 0;
end;
end;
end;

// 调入位图
procedure TForm1.btnLoadClick(Sender: TObject);
begin
Image1.Picture.Bitmap.LoadFromFile(BmpFile);
end;

// 种子填充
procedure TForm1.btnZzTcClick(Sender: TObject);
begin
with Image1.Picture do
Zztc(Bitmap, Bitmap.Width, Bitmap.Height, 40, 30);
Image1.Refresh;
end;

重复操作如下: 调入图像(btnLoadClick)--种子填充(btnZzTcClick)
结果第一次成功,第二次以后就不行了!
非要重新启动程序!!!!!!!!!!

我看了很多关于减少颜色数的贴子,就是搞不明白:像这种本来就只有黑白两色的24位色图,如果将其变为8位图
if bmp.PixelFormat <> pf8bit then
bmp.PixelFormat := pf8bit;
所以请大家帮忙,
 
试过了你的代码,两次结果一致!
 
你的修改部分是什么,位图的位数变化是会引起填充结果的变化的
 
卷起千堆雪tyn:
你的结果如何?装入的图像应该是只有黑白两色的24位图。

menxin:
修改的全部代码在这里了,你看呢?
问题是我重新装入那个位图了,应该和第一次一样了呀?
 
我在 bmp.PixelFormat := pf8bit 后将 bmp 保存为磁盘文件;
前后执行两次,共生成两个文件(都是256色,看上去都是黑白两色)
~~~~~~
再用 UltraEdit Editor 比较它们的二进制数据,
发现两个文件内容并不一样,调色板和图象数据都不一样,
图象数据大部分为 0 和 $13 (应该是系统调色板的黑色和白色),
除此之外还有 7,$B2,$C 等其它的数据,
我想一定是 bmp.PixelFormat := pf8bit 做了什么我不知道的事情,
但我又看不懂 TBitmap.SetPixelFormat ;

卷大侠:
我记得你在哪个贴子里讨论过如何保证256色图象的黑点为0,白色为255
但我找不到了,
 
问得简单吧:
对256色图,如何在己知颜色的情况下,通过调色板设置各点的值???

不会这也没人回答吧?
 
256色位图存储的是对应调色板索引号而非颜色值,
24bit->8bit时会选择时使用当前调色板或系统调色板。
 
[:)] delphi的image控件似乎真是有些问题,以前我也遇到过类似的问题。但我有个百发
百中的方法可以避免这个问题。那就是:
在你的程序中每次使用image装入图形时先用destroy消毁原来的image,然后再动态的
重建一个,就没问题了。
 
已经解决,谢谢各位
macor的意见最接近
 

Similar threads

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