Задать вопрос
@Quiensabe
VR-разработчик

Как открыть 64-битный png средствами delphi или c#?

Добрый день!
Возникла задача открыть 64-битный (16 бит на канал) .png-файл в своей программе.
Обработать его по хитрому алгоритму и сохранить в обычный 32 битный (8 бит на канал) .png-файл.

Проблема - мало опыта, но задачу нужно решить...
Удалось найти, что в dephi это можно сделать через GDI+, но примеры из сети либо вообще не работают, либо требуют старых библиотек и в итоге тоже не работают.
Пишут, что проще это сделать средствами C#. В нем у меня еще меньше опыта, так что совсем не ясно куда копать...

Буду очень благодарен за пример или направление поиска.
Готов на платную консультацию (решение выложу сюда для всех).
Формат исходника не принципиален, могу конвертировать во что угодно.
На крайний случай можно не читать альфа-канал (т.е. прочитать 48-битный файл).

Я уже дошел до того чтобы написать макрос двигающий мышь в фотошопе и читающий пиксели под ней, но фотошоп не показывает значение 16-битных цветов...
  • Вопрос задан
  • 519 просмотров
Подписаться 2 Оценить 1 комментарий
Решения вопроса 1
@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.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@helvit
Вот спецификация формата PNG www.w3.org/TR/PNG
Там есть все необходимое.
А здесь пример от MS https://msdn.microsoft.com/ru-ru/library/aa970062%...
Ответ написан
Taraflex
@Taraflex
Ищу работу. Контакты в профиле.
freeimage.sourceforge.net/download.html
Есть врапперы и под c# и под delphi
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы