ºñÆ®¸ÊÀÇ PixelFormat ¼Ó¼ºÀÌ pf32BitÀÎ TBitmap ¿øº»À¸·ÎºÎÅÍ Å©±âÁ¶Á¤ÇÑ ºñÆ®¸ÊÀ» ¾ò´Â ¼Ò½ºÀÔ´Ï´Ù. Andrew JamesonÀÇ ¿À¸®Áö³Î ¼Ò½º¿¡¼ Transparency °ªÀÌ À¯ÁöµÇµµ·Ï ¼öÁ¤ÇÑ °Í°ú GDI+ API¸¦ ÀÌ¿ëÇÑ °Í Áß¿¡¼ ¼±ÅÃÇÒ ¼ö ÀÖ½À´Ï´Ù.
// Modified(to reserve transparency) version of Andrew Jameson's work. // Src ºñÆ®¸Ê À̹ÌÁö¸¦ Dst ºñÆ®¸ÊÀÇ Å©±â¿¡ ¸ÂÃß¾î Dst ºñÆ®¸Ê¿¡ º¹»çÇÑ´Ù. function SmoothResize(Src, Dst: TBitmap): BOOL; var x, y: Integer; xP, yP: Integer; xP2, yP2: Integer; SrcLine1, SrcLine2: pRGBAArray; t3: Integer; z, z2, iz2: Integer; DstLine: pRGBAArray; DstGap: Integer; w1, w2, w3, w4: Integer; begin Src.PixelFormat := pf32Bit; Dst.PixelFormat := pf32Bit;
if (Src.Width = Dst.Width) and (Src.Height = Dst.Height) then begin Result := true; Dst.Assign(Src); end else try DstLine := Dst.ScanLine[0]; DstGap := Integer(Dst.ScanLine[1]) - Integer(DstLine);
xP2 := MulDiv(pred(Src.Width), $10000, Dst.Width); yP2 := MulDiv(pred(Src.Height), $10000, Dst.Height); yP := 0;
for y := 0 to pred(Dst.Height) do begin xP := 0; SrcLine1 := Src.ScanLine[yP shr 16];
if (yP shr 16 < pred(Src.Height)) then SrcLine2 := Src.ScanLine[succ(yP shr 16)] else SrcLine2 := Src.ScanLine[yP shr 16];
z2 := succ(yP and $FFFF); iz2 := succ((not yp) and $FFFF); for x := 0 to pred(Dst.Width) do begin t3 := xP shr 16; z := xP and $FFFF; w2 := MulDiv(z, iz2, $10000); w1 := iz2 - w2; w4 := MulDiv(z, z2, $10000); w3 := z2 - w4; DstLine[x].rgbRed := (SrcLine1[t3].rgbRed * w1 + SrcLine1[t3 + 1].rgbRed * w2 + SrcLine2[t3].rgbRed * w3 + SrcLine2[t3 + 1].rgbRed * w4) shr 16; DstLine[x].rgbGreen := (SrcLine1[t3].rgbGreen * w1 + SrcLine1[t3 + 1].rgbGreen * w2 + SrcLine2[t3].rgbGreen * w3 + SrcLine2[t3 + 1].rgbGreen * w4) shr 16; DstLine[x].rgbBlue := (SrcLine1[t3].rgbBlue * w1 + SrcLine1[t3 + 1].rgbBlue * w2 + SrcLine2[t3].rgbBlue * w3 + SrcLine2[t3 + 1].rgbBlue * w4) shr 16; DstLine[x].rgbReserved := (SrcLine1[t3].rgbReserved * w1 + SrcLine1[t3 + 1].rgbReserved * w2 + SrcLine2[t3].rgbReserved * w3 + SrcLine2[t3 + 1].rgbReserved * w4) shr 16; Inc(xP, xP2); end; {for} Inc(yP, yP2); DstLine := pRGBAArray(Integer(DstLine) + DstGap); end; {for}
Result := true; except Result := false; end; {try} end; {SmoothResize}
//-------------------------
(»ç¿ë ÇÔ¼ö) {$DEFINE USE_GDIPLUS} function GetResizedBitmap(Bmp: TBitmap; NewSize: TSize): TBitmap; {$IFDEF USE_GDIPLUS} var InputBmp: TGPBitmap; Graphics: TGPGraphics; x, y: integer; P: PARGBArray; GPColor: TGPColor;
// SrcBmp: TGPBitmap; // pixels: pInt; BitmapData: TBitmapData; R: TGPRect; p2: pbyte; {$ENDIF} begin if not Assigned(Bmp) then exit;
// pixel´ç 24bit ¶Ç´Â 32 bit·Î À̹ÌÁö¸¦ ±¸¼ºÇÏ´Â Bitmap¸¸ ó¸®ÇÑ´Ù. if (Bmp.PixelFormat <> pf24Bit) and (Bmp.PixelFormat <> pf32Bit) then exit;
// create graphics object for output image try Result := TBitmap.Create; Result.PixelFormat := bmp.PixelFormat; Result.Width := NewSize.cx; Result.Height := NewSize.cy; {$IFNDEF USE_GDIPLUS} SmoothResize(bmp, Result); // GDI+ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ À̹ÌÁö Å©±âÁ¶Á¤Àº ¾Æ·¡ ÄÚµå ÂüÁ¶. {$ENDIF} except FreeAndNil(Result); exit; end;
{$IFNDEF USE_GDIPLUS} exit; {$ENDIF}
{$IFDEF USE_GDIPLUS} // ¾Æ·¡¿Í °°ÀÌ BitmapÀÇ ÇÚµéÀ» ÀÌ¿ëÇÑ À̹ÌÁö Ãëµæ½Ã´Â ¾ËÆÄä³ÎÀÇ °ªÀ» ÀÒÀº À̹ÌÁö(=ºÒÅõ¸í À̹ÌÁö)¸¦ // ¾ò´Â´Ù. { if (Bmp.PixelFormat in [pf1Bit, pf4Bit, pf8Bit]) then InputBmp := TGPBitmap.Create(Bmp.Handle, Bmp.Palette) else InputBmp := TGPBitmap.Create(Bmp.Handle, 0); }
// ¾Æ·¡¿Í °°ÀÌ Çȼ¿´ÜÀ§ ¶Ç´Â ¶óÀÎ ´ÜÀ§·Î À̹ÌÁö µ¥ÀÌÅ͸¦ Á÷Á¢ º¹»çÇÏ¸é ¾ËÆÄä³ÎÀÇ °ªÀÌ // À¯ÁöµÈ´Ù. // ¶Ç ´Ù¸¥ ¹æ¹ýÀ¸·Î DIB¸¦ ÃëµæÇؼ À̹ÌÁö¸¦ µ¥ÀÌÅ͸¦ Çѹø¿¡ º¹»çÇÏ´Â ¹æ¹ýÀÌ Àִµ¥ ÀÌ °ÍÀº // º°µµ·Î °Ô½ÃÇÑ "¾ËÆÄä³ÎÀÇ °ªÀ» ÀÒÁö ¾Ê°í TBitmapÀ¸·Î ºÎÅÍ GDI+ TGPBitmapÀ» ¾ò´Â ÇÔ¼ö"¿¡ // ³ª¿ÍÀÖ´Ù.
R := MakeRect(0, 0, Bmp.Width, Bmp.Height); // Çȼ¿´ÜÀ§·Î 󸮽ô ºÒÇÊ¿ä if Bmp.AlphaFormat = afPremultiplied then begin InputBmp := TGPBitmap.Create(Bmp.Width, Bmp.Height, PixelFormat32bppPARGB); InputBmp.LockBits(R, ImageLockModeWrite, PixelFormat32bppPARGB, BitmapData); // Çȼ¿´ÜÀ§·Î 󸮽ô ºÒÇÊ¿ä end else begin InputBmp := TGPBitmap.Create(Bmp.Width, Bmp.Height, PixelFormat32bppARGB); InputBmp.LockBits(R, ImageLockModeWrite, PixelFormat32bppARGB, BitmapData); // Çȼ¿´ÜÀ§·Î 󸮽ô ºÒÇÊ¿ä end;
p2 := BitmapData.Scan0; for y := 0 to Bmp.Height - 1 do begin // Çȼ¿´ÜÀ§·Î 󸮽ô ¾Æ·¡ Äڵ带 ÀÌ¿ëÇÑ´Ù. { for x := 0 to (Bmp.Width - 1) do begin GPColor := MakeColor(P[x].rgbReserved, P[x].rgbRed, P[x].rgbGreen, P[x].rgbBlue); InputBmp.SetPixel(x, y, GPColor); end; }
// ¶óÀÎ ´ÜÀ§·Î 󸮽ô ¾Æ·¡ Äڵ带 ÀÌ¿ëÇÑ´Ù. P := Bmp.Scanline[y]; CopyMemory(p2, p, Bmp.Width * 4); inc(p2, BitmapData.Stride); end;
InputBmp.UnlockBits(BitmapData); // Çȼ¿´ÜÀ§·Î 󸮽ô ºÒÇÊ¿ä
try Graphics := TGPGraphics.Create(Result.Canvas.Handle); try // set the composition mode to copy Graphics.SetCompositingMode(CompositingModeSourceCopy); // set high quality rendering modes Graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); Graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality); Graphics.SetSmoothingMode(SmoothingModeHighQuality); // draw the input image on the output in modified size Graphics.DrawImage(InputBmp, 0, 0, Result.Width, Result.Height); finally Graphics.Free; end; finally InputBmp.Free; end;
{$ENDIF} end;
|