Posts tagged ‘greyscale’

libtiff RGB image to greyscale + loading and saving

This example shows you how to load a RGB tiff image, convert it to greyscale and save it as 32 and 8bit greyscale images. It will also write the same RGB image to another file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "tiffio.h"
#include <iostream>
#include <math.h>
#include <vector>
 
using namespace std;
 
class Image {
 
public:
 
  Image() {
  }
 
  void load_tiff(string input_filename) {
 
    m_image_data.clear();
 
    TIFF* tif = TIFFOpen(input_filename.c_str(), "r");
    if (tif) {
      uint32 w, h;
      size_t npixels;
      uint32* raster;
 
      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
      npixels = w * h;
      m_width = w;
      m_height = h;
 
      raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
      if (raster != NULL) {
  if (TIFFReadRGBAImageOriented(tif, w, h, raster,ORIENTATION_TOPLEFT, 0)) {
    for(size_t n=0;n<npixels;n++) m_image_data.push_back(raster&#91;n&#93;);
  }
  _TIFFfree(raster);
      }
      TIFFClose(tif);
    }
  }
 
  void save_tiff_rgb(string output_filename) {
    TIFF *output_image;
 
    // Open the TIFF file
    if((output_image = TIFFOpen(output_filename.c_str(), "w")) == NULL){
      cerr << "Unable to write tif file: " << output_filename << endl;
    }
 
    // We need to set some values for basic tags before we can add any data
    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);
    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);
    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 4);
    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
    // Write the information to the file
    TIFFWriteEncodedStrip(output_image, 0, &m_image_data&#91;0&#93;, m_width*m_height * 4);
 
    // Close the file
    TIFFClose(output_image);
  }
 
  void save_tiff_grey_32bit(string output_filename) {
    TIFF *output_image;
 
    // Open the TIFF file
    if((output_image = TIFFOpen(output_filename.c_str(), "w")) == NULL){
      cerr << "Unable to write tif file: " << output_filename << endl;
    }
 
    // We need to set some values for basic tags before we can add any data
    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);
    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);
    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 32);
    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
 
    // Write the information to the file
    TIFFWriteEncodedStrip(output_image, 0, &m_image_data&#91;0&#93;, m_width*m_height * 4);
 
    // Close the file
    TIFFClose(output_image);
  }
 
  void save_tiff_grey_8bit(string output_filename) {
    TIFF *output_image;
 
    // Open the TIFF file
    if((output_image = TIFFOpen(output_filename.c_str(), "w")) == NULL){
      cerr << "Unable to write tif file: " << output_filename << endl;
    }
 
    // We need to set some values for basic tags before we can add any data
    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);
    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);
    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
 
    // convert data to 8bit
    vector<uint8_t> data;
    for(size_t n=0;n<m_image_data.size();n++) {
      data.push_back(255-(m_image_data&#91;n&#93;/(256*256*256)));
    }
 
    // Write the information to the file
    TIFFWriteEncodedStrip(output_image, 0, &data&#91;0&#93;, m_width*m_height);
 
    // Close the file
    TIFFClose(output_image);
  }
 
  void make_greyscale() {
 
    for(size_t n=0;n<m_image_data.size();n++) {
 
      double r = TIFFGetR(m_image_data&#91;n&#93;);
      double g = TIFFGetG(m_image_data&#91;n&#93;);
      double b = TIFFGetB(m_image_data&#91;n&#93;);
 
      double grey = (0.3*r) + (0.59*g) + (0.11*b); // See http://en.wikipedia.org/wiki/Grayscale
      m_image_data&#91;n&#93; = grey * 256 * 256 * 256;
    }
  }
 
  vector<uint32_t> m_image_data;
  size_t m_width;
  size_t m_height;
};
 
int main(int argc, char* argv[])
{
 
  Image input;
 
  input.load_tiff(string(argv[1]));
  input.save_tiff_rgb(string(argv[2]));
  input.make_greyscale();
  input.save_tiff_grey_32bit(string(argv[3]));
  input.save_tiff_grey_8bit(string(argv[4]));
}

Compile as:

1
g++ makegrey.cpp -ltiff

And run as:

1
./a.out inputfilename.tif rgb.tif 8bitgrey.tif 32bitgrey.tif

Note: The 8bit version is slightly different than the 32bit version. It converts the data such that 0 represents white. This is because Preview.app, at least in MacOS X Lion, does not seem to be able to cope with 0 being black.

This has not been applied to the 32bit output, so this will display incorrectly in Preview. However it will display correctly in Imagemagick.