if (matrix_x<3) or (matrix_y<3) then exit; bitmap:=TBitMap.Create; bitmap.Assign(bit); for y := 0 to bitmap.Height - 1 do begin P := bitmap.ScanLine[y]; for x := 0 to bitmap.Width - 1 do begin pix:= calMean(x,y); p[3 * x + 2] := pix.rgbtRed; p[3 * x + 1] := pix.rgbtGreen; p[3 * x ] := pix.rgbtBlue; end; end; bit.Assign(bitmap); bitmap.Free; 试试看,把bitmap 变量删掉。直接用 bit 是否会错?
pixels 是可以访问,pixels前面用的好的. 错误出现在系统函数@DnyArrayClear里面. 在cpu里看出来的.
问题出现在这个子函数里面红色字.也就是函数结束部分
function calMean(x,y:integer):TRGBTriple;
var pixels:TPixelArray;
r:TRect;
rpix:TRGBTriple;
len,x1,y1,n,m:integer;
begin
r:=Rect(x,y,x+matrix_x-1,y+matrix_y-1);
//平移
x1:=Round(matrix_x/2)-1;
y1:=Round(matrix_y/2)-1;
OffsetRect(r,-x1,-y1); //读矩形内的像素到数组 pixels
ReadPixelArray(bit,r,pixels); len:=high(pixels);
m:=Round(len/2);
//排序数组并取出中值
SortPixelArray(pixels,0,len,tcRed);
rpix.rgbtRed:=pixels[m].rgbtRed;
SortPixelArray(pixels,0,len,tcGreen);
rpix.rgbtGreen:=pixels[m].rgbtGreen;
SortPixelArray(pixels,0,len,tcBlue);
rpix.rgbtBlue:=pixels[m].rgbtBlue;
setLength(pixels,0);
pixels:=nil;
result:= rpix;
end;
可是 PixPtr:=Pic.ScanLine[i]; 返回的是数组的指针再转成数组 应该不是这个问题吧.
我把
PixPtr:=Pic.ScanLine[i];
改成
PixPtr:= TbyteArray(Pic.ScanLine[i]^);
转不了啊...出错: EAccessViolation 地址访问错误."SetLength接收的数组定义" 由于是不定大小的矩形区域所以无法固定接收数组的大小.
tagRGBTRIPLE = packed record
rgbtBlue: Byte;
rgbtGreen: Byte;
rgbtRed: Byte;
end;
TRGBTriple = tagRGBTRIPLE;
我的是图片像素读错了,导致存进数组的为空值
所以虽然他提示是setLength(pixels,0)
建议你检查下前面的像素读取有没错误
bitmap:=TBitMap.Create;
bitmap.Assign(bit);
for y := 0 to bitmap.Height - 1 do
begin
P := bitmap.ScanLine[y];
for x := 0 to bitmap.Width - 1 do
begin
pix:= calMean(x,y);
p[3 * x + 2] := pix.rgbtRed;
p[3 * x + 1] := pix.rgbtGreen;
p[3 * x ] := pix.rgbtBlue;
end;
end;
bit.Assign(bitmap);
bitmap.Free;
试试看,把bitmap 变量删掉。直接用 bit 是否会错?
bit.Assign(bitmap);
能所一下原因吗?代码我已经改成TList了. 原来版本就没保存了.不好意思