//图像缩放过程,带插值运算(线性插值法)
//参数:矩形区域,源图像
//注意:此代码只支持24或32位色的情况(对于15或16位色需要按位拆开—因为不拆开的话
// 会在计算中出现不期望的进位或借位,导致图像颜色混乱—处理较麻烦;对于8位
// 及8位以下索引色需要查调色板,并且需要重索引,也很麻烦,所以都不支持;但
// 8位灰度图像可以支持)。另外代码中加入一些在图像边缘时防止访问越界的代码。
procedure StretchLinear(Dest, Src: TBitmap); // only for 24bit bitmap
var
sw, sh, dw, dh, B, N, x, y, i, j, k, nPixelSize: DWord;
pLinePrev, pLineNext, pDest, pA, pB, pC, pD: PByte;
begin
sw := Src.Width -1;
sh := Src.Height -1;
dw := Dest.Width -1;
dh := Dest.Height -1;
nPixelSize := 3; //GetPixelSize(Dest.PixelFormat)
for i := 0 to dh do begin
pDest := Dest.ScanLine[i];
y := i * sh div dh;
N := dh - i * sh mod dh;
pLinePrev := Src.ScanLine[y];
Inc(y);
if N = dh then begin
pLineNext := pLinePrev;
end else begin
pLineNext := Src.ScanLine[y];
end;
for j := 0 to dw do begin
x := j * sw div dw * nPixelSize;
B := dw - j * sw mod dw;
pA := pLinePrev;
Inc(pA, x);
pB := pA;
Inc(pB, nPixelSize);
pC := pLineNext;
Inc(pC, x);
pD := pC;
Inc(pD, nPixelSize);
if B = dw then begin
pB := pA;
pD := pC;
end;
for k := 0 to nPixelSize -1 do begin
pDest^ := Byte(DWord( (B * N * DWord(pA^ - pB^ - pC^ + pD^) + dw * N * pB^
+ dh * B * pC^ + (dw * dh - dh * B - dw * N)* pD^
+ dw * dh div 2) div (dw * dh) ));
Inc(pDest);
Inc(pA);
Inc(pB);
Inc(pC);
Inc(pD);
end;
end;
end;
end;