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

Post più popolari