Ответы пользователя по тегу Delphi
  • Как открыть 64-битный png средствами delphi или c#?

    @x128
    Набросал небольшой пример на Delphi. Ключевой момент ExtraScanline.
    program Project1;
    
    {$APPTYPE CONSOLE}
    
    uses
      System.SysUtils,
      System.Math,
      Vcl.Imaging.PNGImage;
    
    type
      TRGB = record
        r,g,b: single;
      end;
      TIMG = record
        xmax, ymax: integer;
        data: array of array of TRGB;
      end;
    
    function LoadPNG48(var img: TIMG; const fname: string): boolean;
    var
      png: TPNGImage;
      x,y: integer;
      scan,extra: pRGBLine;
    begin
      png:=TPNGImage.Create;
      png.LoadFromFile(fname);
      result:=png.Header.BitDepth=16;
      if result then begin
        img.xmax:=png.Width;
        img.ymax:=png.Height;
        SetLength(img.data, png.Height, png.Width);
        for y:=0 to img.ymax-1 do begin
          scan:=png.Scanline[y];
          extra:=png.ExtraScanline[y];
          for x:=0 to img.xmax-1 do begin
            img.data[y,x].r:=(scan[x].rgbtRed shl 8 + extra[x].rgbtRed) / 65535;
            img.data[y,x].g:=(scan[x].rgbtGreen shl 8 + extra[x].rgbtGreen) / 65535;
            img.data[y,x].b:=(scan[x].rgbtBlue shl 8 + extra[x].rgbtBlue) / 65535;
          end;
        end;
      end;
      png.Free;
    end;
    
    procedure SavePNG24(var img: TIMG; const fname: string);
    var
      png: TPNGImage;
      x,y: integer;
      scan: pRGBLine;
    begin
      png:=TPNGImage.CreateBlank(COLOR_RGB, 8, img.xmax, img.ymax);
      for y:=0 to img.ymax-1 do begin
        scan:=png.Scanline[y];
        for x:=0 to img.xmax-1 do begin
          scan[x].rgbtRed:=round(img.data[y,x].r*255);
          scan[x].rgbtGreen:=round(img.data[y,x].g*255);
          scan[x].rgbtBlue:=round(img.data[y,x].b*255);
        end;
      end;
      png.SaveToFile(fname);
    end;
    
    var
      img: TIMG;
      x,y: integer;
    begin
      if LoadPNG48(img, 'test48.png') then begin
        for y:=0 to img.ymax-1 do begin
          for x:=0 to img.xmax-1 do begin
            img.data[y,x].r:=power(img.data[y,x].r, 1 / 2.2);
            img.data[y,x].g:=power(img.data[y,x].g, 1 / 2.2);
            img.data[y,x].b:=power(img.data[y,x].b, 1 / 2.2);
          end;
        end;
        SavePNG24(img, 'test24.png');
      end;
    end.
    Ответ написан
    1 комментарий