### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [SOLVED] Tiff 16 bit grayscale pixel access?  (Read 14347 times)

#### DomingoGP

• New Member
• Posts: 15
##### Re: Tiff 16 bit grayscale pixel access?
« Reply #15 on: May 20, 2021, 10:34:10 pm »
Hi

You can read the elevation data using the libTiff library.

You can use TIFFReadScanline for reading the raw data.

Here is a quick and dirty sample loading the raw data without color conversions.
If the format of the tiff is tiled then the sample will not work.

The code reads a 'test.tif' image in the same folder.

I don't include the image because the size is > 500kb and the forum dont allow me to attach it.

I hope this code works for you.

#### engkin

• Hero Member
• Posts: 2853
##### Re: Tiff 16 bit grayscale pixel access?
« Reply #16 on: May 21, 2021, 12:22:11 am »
The image is not black. To be precise, the max value of the sample image is 1566. This value is close to black: 0. On a linear scale it is about 2.4%

The sample file is tiled 15x15 tiles. It has 9 "pages" or images. FPReadTiff is able to read it. It does not recognize 6 tags from the first image:
Quote
TFPReaderTiff.ReadDirectoryEntry Tag 262: PhotometricInterpretation=1=bilevel grayscale 0 is black

Sample code to read the image, find the max value, and "brighten" the image before saving it to "out1.jpg"
Code: Pascal  [Select][+][-]
1. uses
2. ...
4.
5. function FindMax(Img:TFPCustomImage):word;
6. var
7.   y, x: Integer;
8.   v: Word;
9. begin
10.   Result := 0;
11.   for y:=0 to Img.Height-1 do
12.   begin
13.     for x := 0 to Img.Width-1 do
14.     begin
15.       v := Img.Colors[x,y].Red;
16.       if v>Result then
17.         Result := v;
18.     end;
19.   end;
20. end;
21.
22. procedure BrightenImg(Img: TFPCustomImage; maxV: word);
23. var
24.   y, x: Integer;
25.   v: Word;
26. begin
27.   for y:=0 to Img.Height-1 do
28.   begin
29.     for x := 0 to Img.Width-1 do
30.     begin
31.       v := Img.Colors[x,y].Red;
32.       v := ((\$FFFF*v) div maxV) and \$FFFF;
33.       Img.Colors[x,y] := FPColor(v,v,v);
34.     end;
35.   end;
36. end;
37.
38. procedure TiffToJpg(fn:String='ASTGTMV003_N45E012_dem.tif');
39. var
41.   Img:TFPMemoryImage;
42.   maxV: Word;
43. begin
44.
45.   Img:=TFPMemoryImage.Create(0,0);
46.   try
47.     r := TFPReaderTiff.Create;
48.     r.Debug:=True;
49.     try
50.       Img.loadfromfile (fn, r);
51.       WriteLn('Img.Width: ', Img.Width);
52.       WriteLn('Img.Height: ', Img.Height);
53.
54.       maxV := FindMax(Img);
55.       WriteLn('Max value: ', maxV);
56.
57.       BrightenImg(Img, maxV);
58.       Img.SaveToFile('out1.jpg');
59.     finally
60.       r.Free;
61.     end;
62.   finally
63.     Img.Free;
64.   end;
65. end;
« Last Edit: May 21, 2021, 12:29:51 am by engkin »

#### Frate

• New Member
• Posts: 23
##### Re: Tiff 16 bit grayscale pixel access?
« Reply #17 on: May 21, 2021, 01:28:24 am »
IrfanView was the only program on my PC to display this file. However, a Lazarus program based on the freeimage.dll is able to display something too, although it is in some kind of false colors - but at least it is something. I don't want to spend too much time in this, but when you play with freeimage you can probably find settings which show the image correctly.

My demo program is in the attachment. If you are on Windows you can download the pre-compiled freeimage.dll from https://freeimage.sourceforge.io/download.html; copy it into the folder with the exe of the demo program.

Working good! However i couldnt figure out the correct reading settings, tried numerous combinations but no luck. I  looked also to the raw binary value to see if i could identify some patterns in the value but its taking too much time as you said. Thanks for your help.

The image is not black. To be precise, the max value of the sample image is 1566. This value is close to black: 0. On a linear scale it is about 2.4%

The sample file is tiled 15x15 tiles. It has 9 "pages" or images. FPReadTiff is able to read it. It does not recognize 6 tags from the first image:
Quote
TFPReaderTiff.ReadDirectoryEntry Tag 262: PhotometricInterpretation=1=bilevel grayscale 0 is black

Sample code to read the image, find the max value, and "brighten" the image before saving it to "out1.jpg"
Code: Pascal  [Select][+][-]
1. uses
2. ...
4.
5. function FindMax(Img:TFPCustomImage):word;
6. var
7.   y, x: Integer;
8.   v: Word;
9. begin
10.   Result := 0;
11.   for y:=0 to Img.Height-1 do
12.   begin
13.     for x := 0 to Img.Width-1 do
14.     begin
15.       v := Img.Colors[x,y].Red;
16.       if v>Result then
17.         Result := v;
18.     end;
19.   end;
20. end;
21.
22. procedure BrightenImg(Img: TFPCustomImage; maxV: word);
23. var
24.   y, x: Integer;
25.   v: Word;
26. begin
27.   for y:=0 to Img.Height-1 do
28.   begin
29.     for x := 0 to Img.Width-1 do
30.     begin
31.       v := Img.Colors[x,y].Red;
32.       v := ((\$FFFF*v) div maxV) and \$FFFF;
33.       Img.Colors[x,y] := FPColor(v,v,v);
34.     end;
35.   end;
36. end;
37.
38. procedure TiffToJpg(fn:String='ASTGTMV003_N45E012_dem.tif');
39. var
41.   Img:TFPMemoryImage;
42.   maxV: Word;
43. begin
44.
45.   Img:=TFPMemoryImage.Create(0,0);
46.   try
47.     r := TFPReaderTiff.Create;
48.     r.Debug:=True;
49.     try
50.       Img.loadfromfile (fn, r);
51.       WriteLn('Img.Width: ', Img.Width);
52.       WriteLn('Img.Height: ', Img.Height);
53.
54.       maxV := FindMax(Img);
55.       WriteLn('Max value: ', maxV);
56.
57.       BrightenImg(Img, maxV);
58.       Img.SaveToFile('out1.jpg');
59.     finally
60.       r.Free;
61.     end;
62.   finally
63.     Img.Free;
64.   end;
65. end;

Engkin this is perfect! All fp also, best solution.
It's also quite fast, I'm able to make 1000000 pixel calls a second which is more than good enough for now.
About the unrecognized tags, i'm actually not interested in them. they basically give geo position info of the tile (i guess), which i dont need.

Hi

You can read the elevation data using the libTiff library.

You can use TIFFReadScanline for reading the raw data.

Here is a quick and dirty sample loading the raw data without color conversions.
If the format of the tiff is tiled then the sample will not work.

The code reads a 'test.tif' image in the same folder.

I don't include the image because the size is > 500kb and the forum dont allow me to attach it.

I hope this code works for you.

Thanks DomingoGP, I'll compare your solution to the one from Engkin. Lets see which one is faster.
About tiled format I think I need only the first image, but I'm checking.

Thank you all for helping out!

I'll keep you posted on the final choice

Frate

#### Frate

• New Member
• Posts: 23
##### [Solved] Tiff 16 bit grayscale pixel access?
« Reply #18 on: May 21, 2021, 11:53:09 am »
Allright, in the end Engkin's code works the best.
It allows me to get a pretty big improvement in data quality.
See attached image (its a terrain section), green is old, red new data.

Again thanks all

Great community! Best wishes for everyone

Frate
« Last Edit: May 21, 2021, 11:57:53 am by Frate »