[Delphi] TImage - PNG - Stretch

0

Witam , mam następujący problem z obrazkiem PNG : gdy chciałbym zmienić jego rozmiar poprzez stretch jakość drastycznie spada :| (wiem że mogę sobie sam go własnoręcznie zrobić mniejsze ale nie opłaca mi się ponieważ ma to być wiele rozmiarów tego samego PNG) Byłoby to wygodniejsze , no ale zobaczcie :
user image
Na pierwszym jest obrazek zaraz po załadowaniu (są to trzy TImage) , drugi natomiast jest też po załadowaniu ale ma włączone stretch i domyslne rozmiary - widzimy jakość beznadziejna , trzeci jest tak jak drugi tylko że dodatkowo zmniejszony.

No i zależy mi żeby móc zmieniać rozmiar TImage z Stretch z PNG bez takich problemów.
Próbowałem z TImage32 (z Graphic32) ale tam nie mogę zrobić przezroczystości PNG.

Proszę o pomoc :)

0

tu masz BitmapResize.pas : http://www.przeklej.pl/plik/bitmapresize-pas-001b9d2kp7tb

a w nim :

procedure ResizeBicubic(Src: TBitmap; var Dest: TBitmap;
  DestWidth, DestHeight, SrcWidth, SrcHeight: integer);

procedure ResizeBilinear(Src: TBitmap; var Dest: TBitmap;
  DestWidth, DestHeight, SrcWidth, SrcHeight: integer);

procedure ResizeNearestNeighbor(Src: TBitmap; var Dest: TBitmap;
  DestWidth, DestHeight, SrcWidth, SrcHeight: integer);

Chodzi o to, że jak użyjesz, któreś z tych funkcji, to obraz będzie mniej zepsuty niż przez Stretch.

0

Dzięki za odp. zaraz sprawdzę , no ale co z przezroczystością !? W bitmapie przecież nie ma przezroczystości.

0

Google + Ctrl C + Ctrl V = 3ms

procedure copy_to_resized_png( tar, src:string; w, h: Integer);
  var
    bmp: TBitmap;
    png, output: TPngImage;
  begin
    png := TPngImage.Create;
    png.LoadFromFile( src);

    bmp := TBitmap.Create;
    bmp.Width := w;
    bmp.Height := h;

    bmp.Canvas.StretchDraw( RECT( 0, 0, w, h), png);

    output := TPngImage.Create;
    output.Assign( bmp);
    output.SaveToFile( tar);

    output.Free;
    bmp.Free;
    png.Free;
  end;
0

@lankusiek, dzięki obudziłeś mnie :)

Co prawda twój sposób mnie nie interesuje bo nie zachowa on przezroczystości , ale sam znalazłem odp.

Ja szukałem odpowiedzi jak naprawić stretch w Timage z PNG , a trzeba było szukać jak zmienić rozmiar PNG :)

Dla pokoleń :

Resizes a TPNGObject using a smooth algorithm

procedure SmoothResize(apng:tpngobject; NuWidth,NuHeight:integer)
User rating [435 user(s)]:
(Click on a star to rate)

by Gustavo Daud (Submited on 9 May 2006 )

Use this method to resize RGB and RGB Alpha 'Portable Network Graphics' Images using a smooth antialiased algorithm in order to get much better results.

This is only possible when using the 1.56 library version.

procedure SmoothResize(apng:tpngobject; NuWidth,NuHeight:integer);
var
  xscale, yscale         : Single;
  sfrom_y, sfrom_x       : Single;
  ifrom_y, ifrom_x       : Integer;
  to_y, to_x             : Integer;
  weight_x, weight_y     : array[0..1] of Single;
  weight                 : Single;
  new_red, new_green     : Integer;
  new_blue, new_alpha    : Integer;
  new_colortype          : Integer;
  total_red, total_green : Single;
  total_blue, total_alpha: Single;
  IsAlpha                : Boolean;
  ix, iy                 : Integer;
  bTmp : TPNGObject;
  sli, slo : pRGBLine;
  ali, alo: pbytearray;
begin
  if not (apng.Header.ColorType in [COLOR_RGBALPHA, COLOR_RGB]) then
    raise Exception.Create('Only COLOR_RGBALPHA and COLOR_RGB formats' +
    ' are supported');
  IsAlpha := apng.Header.ColorType in [COLOR_RGBALPHA];
  if IsAlpha then new_colortype := COLOR_RGBALPHA else
    new_colortype := COLOR_RGB;
  bTmp := Tpngobject.CreateBlank(new_colortype, 8, NuWidth, NuHeight);
  xscale := bTmp.Width / (apng.Width-1);
  yscale := bTmp.Height / (apng.Height-1);
  for to_y := 0 to bTmp.Height-1 do begin
    sfrom_y := to_y / yscale;
    ifrom_y := Trunc(sfrom_y);
    weight_y[1] := sfrom_y - ifrom_y;
    weight_y[0] := 1 - weight_y[1];
    for to_x := 0 to bTmp.Width-1 do begin
      sfrom_x := to_x / xscale;
      ifrom_x := Trunc(sfrom_x);
      weight_x[1] := sfrom_x - ifrom_x;
      weight_x[0] := 1 - weight_x[1];

      total_red   := 0.0;
      total_green := 0.0;
      total_blue  := 0.0;
      total_alpha  := 0.0;
      for ix := 0 to 1 do begin
        for iy := 0 to 1 do begin
          sli := apng.Scanline[ifrom_y + iy];
          if IsAlpha then ali := apng.AlphaScanline[ifrom_y + iy];
          new_red := sli[ifrom_x + ix].rgbtRed;
          new_green := sli[ifrom_x + ix].rgbtGreen;
          new_blue := sli[ifrom_x + ix].rgbtBlue;
          if IsAlpha then new_alpha := ali[ifrom_x + ix];
          weight := weight_x[ix] * weight_y[iy];
          total_red   := total_red   + new_red   * weight;
          total_green := total_green + new_green * weight;
          total_blue  := total_blue  + new_blue  * weight;
          if IsAlpha then total_alpha  := total_alpha  + new_alpha  * weight;
        end;
      end;
      slo := bTmp.ScanLine[to_y];
      if IsAlpha then alo := bTmp.AlphaScanLine[to_y];
      slo[to_x].rgbtRed := Round(total_red);
      slo[to_x].rgbtGreen := Round(total_green);
      slo[to_x].rgbtBlue := Round(total_blue);
      if isAlpha then alo[to_x] := Round(total_alpha);
    end;
  end;
  apng.Assign(bTmp);
  bTmp.Free;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1