Scintilla Screenshot resize
Per potere inviare uno screenshot o un video (inteso come sequenza di screenshot) dal client al server è necessario ottenere uno screenshot. Il server non necessita di uno screenshot di dimensioni reali ma di un thumbnails di circa 136x72 pixel e di una immagine più grande di circa 800x450. Una volta ottenuto il Bitmap si può effettuare il resize con due tecniche diverse: chiamare la StretchBlt di Windows oppure agire direttamente sulle scanlines del Bitmap. In questo esempio sono mostrate tutte e due le tecniche. Qui trovi una tecnica avanzata.
Type TRGB = packed record
b: byte;
g: byte;
r: byte;
end;
type RGBROW = array[0..Maxint div 16] of TRGB;
type PRGB = ^TRGB;
type PRGBROW = ^RGBROW;
procedure TForm1.GetScreenShot () ;
var
Win: HWND;
DC: HDC;
Bmp,BmpSmall,BmpLarge: TBitmap;
x, y: Integer;
zx, zy: Double;
sxarr: array of Integer;
dst_rgb: PRGB;
src_rgb: PRGBROW;
start: integer;
ScreenshotW : integer;
ScreenshotH : integer;
VideoW : integer;
VideoH : integer;
begin
ScreenshotW := 136;
ScreenshotH := 72;
VideoW := 800;
VideoH := 450;
DC:= GetWindowDC(GetDesktopWindow);
Caption:='';
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf24bit;
Bmp.Height := Screen.Height ;
Bmp.Width :=Screen.Width ;
BitBlt(Bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DC, 0, 0, SRCCOPY);
BmpSmall := TBitmap.Create;
BmpSmall.Width := ScreenshotW;
BmpSmall.Height := ScreenshotH;
BmpSmall.pixelformat:= pf24bit;
BmpLarge := TBitmap.Create;
BmpLarge.Width := VideoW;
BmpLarge.Height := VideoH;
BmpLarge.pixelformat:= pf24bit;
// Resize Windows Api su BmpSmall
SetStretchBltMode(BmpSmall.Handle,HALFTONE);
start:= getTickcount;
StretchBlt(BmpSmall.Canvas.Handle,0,0,BmpSmall.Width,BmpSmall.Height, Bmp.Canvas.Handle ,0,0,Bmp.Width,Bmp.Height,SRCCOPY );
caption:= 'stretchblt: ' +inttostr (gettickCount -start);
start:= getTickcount;
// Resize manuale senza api di Windows su BmpSmall
zx := bmp.Width / ScreenshotW;
zy := bmp.Height / ScreenshotH;
SetLength(sxarr, ScreenshotW);
for x := 0 to ScreenshotW - 1 do
sxarr[x] := trunc(x * zx);
for y := 0 to ScreenshotH - 1 do
begin
src_rgb := bmp.Scanline[trunc(y * zy)];
dst_rgb := BmpSmall.Scanline[y];
for x := 0 to BmpSmall.Width - 1 do
begin
dst_rgb^ := src_rgb[sxarr[x]];
inc(dst_rgb);
end;
end;
caption:= caption + ' manual: ' + inttostr (gettickCount -start);
// Resize Windows Api su BmpLarge
SetStretchBltMode(BmpLarge.Handle,HALFTONE);
start:= getTickcount;
StretchBlt(BmpLarge.Canvas.Handle,0,0,BmpLarge.Width,BmpLarge.Height, Bmp.Canvas.Handle ,0,0,Bmp.Width,Bmp.Height,SRCCOPY );
caption:= 'stretchblt: ' +inttostr (gettickCount -start);
start:= getTickcount;
// Resize manuale senza api di Windows su BmpLarge
zx := bmp.Width /VideoW;
zy := bmp.Height / VideoH;
SetLength(sxarr, VideoW);
for x := 0 to VideoW - 1 do
sxarr[x] := trunc(x * zx);
for y := 0 to VideoH - 1 do
begin
src_rgb := bmp.Scanline[trunc(y * zy)];
dst_rgb := BmpLarge.Scanline[y];
for x := 0 to BmpLarge.Width - 1 do
begin
dst_rgb^ := src_rgb[sxarr[x]];
inc(dst_rgb);
end;
end;
caption:= caption + ' manual: ' + inttostr (gettickCount -start);
Bmp.Free;
ReleaseDC(Win, DC);
end;

Commenti
Posta un commento