{"id":549,"date":"2011-10-30T20:29:08","date_gmt":"2011-10-30T20:29:08","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=549"},"modified":"2011-10-30T20:29:08","modified_gmt":"2011-10-30T20:29:08","slug":"libtiff-rgb-image-to-greyscale-loading-and-saving","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2011\/10\/libtiff-rgb-image-to-greyscale-loading-and-saving\/","title":{"rendered":"libtiff RGB image to greyscale + loading and saving"},"content":{"rendered":"<p>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.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &quot;tiffio.h&quot;\r\n#include &lt;iostream&gt;\r\n#include &lt;math.h&gt;\r\n#include &lt;vector&gt;\r\n\r\nusing namespace std;\r\n\r\nclass Image {\r\n\r\npublic:\r\n\r\n  Image() {\r\n  }\r\n\r\n  void load_tiff(string input_filename) {\r\n\r\n    m_image_data.clear();\r\n\r\n    TIFF* tif = TIFFOpen(input_filename.c_str(), &quot;r&quot;);\r\n    if (tif) {\r\n      uint32 w, h;\r\n      size_t npixels;\r\n      uint32* raster;\r\n\r\n      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &amp;w);\r\n      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;h);\r\n      npixels = w * h;\r\n      m_width = w;\r\n      m_height = h;\r\n\r\n      raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));\r\n      if (raster != NULL) {\r\n\tif (TIFFReadRGBAImageOriented(tif, w, h, raster,ORIENTATION_TOPLEFT, 0)) {\r\n\t  for(size_t n=0;n&lt;npixels;n++) m_image_data.push_back(raster&amp;#91;n&amp;#93;);\r\n\t}\r\n\t_TIFFfree(raster);\r\n      }\r\n      TIFFClose(tif);\r\n    }\r\n  }\r\n\r\n  void save_tiff_rgb(string output_filename) {\r\n    TIFF *output_image;\r\n\r\n    \/\/ Open the TIFF file\r\n    if((output_image = TIFFOpen(output_filename.c_str(), &quot;w&quot;)) == NULL){\r\n      cerr &lt;&lt; &quot;Unable to write tif file: &quot; &lt;&lt; output_filename &lt;&lt; endl;\r\n    }\r\n\r\n    \/\/ We need to set some values for basic tags before we can add any data\r\n    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);\r\n    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);\r\n    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);\r\n    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 4);\r\n    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);\r\n\r\n    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);\r\n    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);\r\n\r\n    \/\/ Write the information to the file\r\n    TIFFWriteEncodedStrip(output_image, 0, &amp;m_image_data&amp;#91;0&amp;#93;, m_width*m_height * 4);\r\n\r\n    \/\/ Close the file\r\n    TIFFClose(output_image);\r\n  }\r\n\r\n  void save_tiff_grey_32bit(string output_filename) {\r\n    TIFF *output_image;\r\n\r\n    \/\/ Open the TIFF file\r\n    if((output_image = TIFFOpen(output_filename.c_str(), &quot;w&quot;)) == NULL){\r\n      cerr &lt;&lt; &quot;Unable to write tif file: &quot; &lt;&lt; output_filename &lt;&lt; endl;\r\n    }\r\n\r\n    \/\/ We need to set some values for basic tags before we can add any data\r\n    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);\r\n    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);\r\n    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 32);\r\n    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 1);\r\n    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);\r\n\r\n    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);\r\n    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);\r\n\r\n    \/\/ Write the information to the file\r\n    TIFFWriteEncodedStrip(output_image, 0, &amp;m_image_data&amp;#91;0&amp;#93;, m_width*m_height * 4);\r\n\r\n    \/\/ Close the file\r\n    TIFFClose(output_image);\r\n  }\r\n\r\n  void save_tiff_grey_8bit(string output_filename) {\r\n    TIFF *output_image;\r\n\r\n    \/\/ Open the TIFF file\r\n    if((output_image = TIFFOpen(output_filename.c_str(), &quot;w&quot;)) == NULL){\r\n      cerr &lt;&lt; &quot;Unable to write tif file: &quot; &lt;&lt; output_filename &lt;&lt; endl;\r\n    }\r\n\r\n    \/\/ We need to set some values for basic tags before we can add any data\r\n    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);\r\n    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);\r\n    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);\r\n    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 1);\r\n    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);\r\n\r\n    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);\r\n    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);\r\n\r\n    \/\/ convert data to 8bit\r\n    vector&lt;uint8_t&gt; data;\r\n    for(size_t n=0;n&lt;m_image_data.size();n++) {\r\n      data.push_back(255-(m_image_data&amp;#91;n&amp;#93;\/(256*256*256)));\r\n    }\r\n\r\n    \/\/ Write the information to the file\r\n    TIFFWriteEncodedStrip(output_image, 0, &amp;data&amp;#91;0&amp;#93;, m_width*m_height);\r\n\r\n    \/\/ Close the file\r\n    TIFFClose(output_image);\r\n  }\r\n\r\n  void make_greyscale() {\r\n\r\n    for(size_t n=0;n&lt;m_image_data.size();n++) {\r\n\r\n      double r = TIFFGetR(m_image_data&amp;#91;n&amp;#93;);\r\n      double g = TIFFGetG(m_image_data&amp;#91;n&amp;#93;);\r\n      double b = TIFFGetB(m_image_data&amp;#91;n&amp;#93;);\r\n\r\n      double grey = (0.3*r) + (0.59*g) + (0.11*b); \/\/ See http:\/\/en.wikipedia.org\/wiki\/Grayscale\r\n      m_image_data&amp;#91;n&amp;#93; = grey * 256 * 256 * 256;\r\n    }\r\n  }\r\n\r\n  vector&lt;uint32_t&gt; m_image_data;\r\n  size_t m_width;\r\n  size_t m_height;\r\n};\r\n\r\nint main(int argc, char* argv&#x5B;])\r\n{\r\n\r\n  Image input;\r\n\r\n  input.load_tiff(string(argv&#x5B;1]));\r\n  input.save_tiff_rgb(string(argv&#x5B;2]));\r\n  input.make_greyscale();\r\n  input.save_tiff_grey_32bit(string(argv&#x5B;3]));\r\n  input.save_tiff_grey_8bit(string(argv&#x5B;4]));\r\n}\r\n<\/pre>\n<p>Compile as:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ng++ makegrey.cpp -ltiff\r\n<\/pre>\n<p>And run as:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n.\/a.out inputfilename.tif rgb.tif 8bitgrey.tif 32bitgrey.tif\r\n<\/pre>\n<p>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.<\/p>\n<p>This has not been applied to the 32bit output, so this will display incorrectly in Preview. However it will display correctly in Imagemagick.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. #include &quot;tiffio.h&quot; #include &lt;iostream&gt; #include &lt;math.h&gt; #include &lt;vector&gt; using namespace std; class Image { public: Image() { } void load_tiff(string [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[17,15],"class_list":["post-549","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-greyscale","tag-libtiff"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-8R","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/549","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=549"}],"version-history":[{"count":2,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/549\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/549\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=549"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=549"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=549"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}