Answer the question
In order to leave comments, you need to log in
How to open 64-bit png with delphi or c#?
Good afternoon!
There was a task to open a 64-bit (16 bit per channel) .png file in my program.
Process it using a tricky algorithm and save it as a regular 32 bit (8 bit per channel) .png file.
The problem is little experience, but the task needs to be solved...
I managed to find that in dephi this can be done through GDI +, but the examples from the network either do not work at all, or require old libraries and, as a result, do not work either.
They write that it is easier to do this using C #. I have even less experience in it, so it's not at all clear where to dig ...
I would be very grateful for an example or direction to search.
Ready for a paid consultation (I'll post the solution here for everyone).
The format of the source is not important, I can convert to anything.
In extreme cases, you can not read the alpha channel (i.e. read a 48-bit file).
I've already gone so far as to write a macro to move the mouse in photoshop and read the pixels below it, but photoshop doesn't show the value of 16-bit colors...
Answer the question
In order to leave comments, you need to log in
Sketched a small example on Delphi. The key point of 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.
Here's the PNG specification www.w3.org/TR/PNG
Everything you need is there.
And here is an example from MS https://msdn.microsoft.com/ru-ru/library/aa970062%...
freeimage.sourceforge.net/download.html
There are wrappers for both c# and delphi
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question