How to remove tiff tags using LibTiff.Net 2.3 library

I can not find the documentation on how to remove the tiff tag using the LibTiff.Net library. I like the library, but this method is important for what I need to do. At some point, I was hoping that I could just set the tag and set its value to nothing. I was hoping this would work, but it was negative.

Does anyone know how to remove the tiff tag using the LibTiff.Net library?

+4
source share
3 answers

Note. At first this may seem like a great answer, but I wanted to make sure that the one who looks at it sees all the "own classes that I created to keep everything boxed for cleanliness." In the interest of preserving the answer as much as possible, and to be informative, I only insert the code for the DeleteTiffTags method. The rest of the code can be downloaded via here .

Now about the good things ... In the end, I spent about a day for this to happen, and this was made possible thanks to various questions that the large stackoverflow community answers. I wrote two small (very detailed) methods in one of my classes to remove the tiff tag. The first one is for deleting the list of specified tags, and the second one is for deleting one tag that works with the specified method. Also in this example, I added a few lines to support my custom tiff tags ... They will be preceded by // ADDED comment.

Classes:

public static class TIFFTAGS - This class is the main class, which is simply called by doing something like TIFFTAGS.DeleteTiffTags (); Since this is a static class, there is no need to create an object in order to use its methods.

private class TIFFTAGS_PAGE - This class is a private class that is located inside the TIFFTAGS class. The goal is to contain all the information about one page for all the pages that may be in tiff. It is private and is used only for internal purposes.

public class TIFFTAGS_TAG - This is the class that I did to wrap tags in something more than I like. Uses standard tag type names such as ASCII, SHORT, LONG, and RATIONAL.

Methods / Functions:

TagExtender () - This little gem is a callback function that allows you to actually save your custom tags in tiff. Without it, ALL of your custom tags will disappear when you delete any tag (even if you deleted only one).

DeleteTiffTags () - This is the main method that deletes a list of tags. Just go to the list of ushort tag numbers and everything will be deleted. Keep in mind without using the TagExtender function, it will call your custom puff tags!

DeleteTiffTag () - This is simply used to delete a single tiff tag. It calls DeleteTiffTags () to handle grunt work.

public static bool DeleteTiffTags(string sFileName, List<ushort> ushortTagNumbers) { //Deletes a list of tiff tag from the given image //Returns true if successful or false if error occured //Define variables List<TIFFTAGS_PAGE> ttPage = new List<TIFFTAGS_PAGE>(); //Check for empty list if (ushortTagNumbers.Count == 0) return false; try { //ADDED m_lTagsToWrite = new List<TIFFTAGS_TAG>(); m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38001, Convert.ToString(""))); m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38002, Convert.ToString(""))); m_parentExtender = Tiff.SetTagExtender(TagExtender); //Open the file for reading using (Tiff input = Tiff.Open(sFileName, "r")) { if (input == null) return false; //Get page count int numberOfDirectories = input.NumberOfDirectories(); //Go through all the pages for (short i = 0; i < numberOfDirectories; ++i) { //Set the page input.SetDirectory(i); //Create a new tags dictionary to store all my tags Dictionary<ushort, FieldValue[]> dTags = new Dictionary<ushort, FieldValue[]>(); //Get all the tags for the page for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t) { TiffTag tag = (TiffTag)t; FieldValue[] tagValue = input.GetField(tag); if (tagValue != null) { dTags.Add(t, tagValue); } } //Check if the page is encoded bool encoded = false; FieldValue[] compressionTagValue = input.GetField(TiffTag.COMPRESSION); if (compressionTagValue != null) encoded = (compressionTagValue[0].ToInt() != (int)Compression.NONE); //Create a new byte array to store all my image data int numberOfStrips = input.NumberOfStrips(); byte[] byteImageData = new byte[numberOfStrips * input.StripSize()]; int offset = 0; //Get all the image data for the page for (int n = 0; n < numberOfStrips; ++n) { int bytesRead; if (encoded) bytesRead = input.ReadEncodedStrip(n, byteImageData, offset, byteImageData.Length - offset); else bytesRead = input.ReadRawStrip(n, byteImageData, offset, byteImageData.Length - offset); //Add to the offset keeping up with where we are offset += bytesRead; } //Save all the tags, image data, and height, etc for the page TIFFTAGS_PAGE tiffPage = new TIFFTAGS_PAGE(); tiffPage.Height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); tiffPage.Tags = dTags; tiffPage.PageData = byteImageData; tiffPage.Encoded = encoded; tiffPage.StripSize = input.StripSize(); tiffPage.StripOffset = input.GetField(TiffTag.STRIPOFFSETS)[0].ToIntArray()[0]; ttPage.Add(tiffPage); } } //Open the file for writing using (Tiff output = Tiff.Open(sFileName + "-new.tif", "w")) { if (output == null) return false; //Go through all the pages for (short i = 0; i < ttPage.Count(); ++i) { //Write all the tags for the page foreach (KeyValuePair<ushort, FieldValue[]> tagValue in ttPage[i].Tags) { //Write all the tags except the one needing to be deleted if (!ushortTagNumbers.Contains(tagValue.Key)) { TiffTag tag = (TiffTag)tagValue.Key; output.GetTagMethods().SetField(output, tag, tagValue.Value); } } //Set the height for the page output.SetField(TiffTag.ROWSPERSTRIP, ttPage[i].Height); //Set the offset for the page output.SetField(TiffTag.STRIPOFFSETS, ttPage[i].StripOffset); //Save page data along with tags output.CheckpointDirectory(); //Write each strip one at a time using the same orginal strip size int numberOfStrips = ttPage[i].PageData.Length / ttPage[i].StripSize; int offset = 0; for (int n = 0; n < numberOfStrips; ++n) { //Write all the image data (strips) for the page if (ttPage[i].Encoded) //output.WriteEncodedStrip(n, byteStrip, offset, byteStrip.Length - offset); output.WriteEncodedStrip(0, ttPage[i].PageData, offset, ttPage[i].StripSize - offset); else output.WriteRawStrip(n, ttPage[i].PageData, offset, ttPage[i].StripSize - offset); //Add to the offset keeping up with where we are offset += ttPage[i].StripOffset; } //Save the image page output.WriteDirectory(); } } //ADDED Tiff.SetTagExtender(m_parentExtender); } catch { //ADDED Tiff.SetTagExtender(m_parentExtender); //Error occured return false; } //Return success return true; } 
+1
source

Pay attention to the TiffCP utility (and especially its source code) that comes with LibTiff.Net.

LibTiff.Net does not offer methods for removing tags (the same is true for LibTiff). To do this, you will need to implement part of the TiffCP functions.

Basically, you will need to copy all the tags you want to keep and copy the pixel data without decoding and re-encoding.

Also note the Convert multi-page TIFF image to a single-line one . It shows how to copy tags and copy raw (non-encoded data) from one image to another. The sample actually decodes the data in some cases, because it needs to change the number of bands, but you will not need to decode the data.

+3
source

I think you will have to basically copy the input file into a new TIFF image, filtering out the tags you don't want in the process. Take a look at the tiffcp utility, which is part of the regular libtiff distribution. This is similar to minus filtering.

Disclaimer: I have never used LibTiff.Net and suggest that it is very similar to LibTiff.

Take a look at tiffcp.c

First, he manually copies / sets some well-known tags, such as resolution, compression, colors, etc. Then it copies all the tags that can be copied without preprocessing:

 for (p = tags; p < &tags[NTAGS]; p++) CopyTag(p->tag, p->count, p->type); 

Then it copies the actual pixel data. It will be from what I recall to remove tags that are not known to tiffcp. If your tag that you want to remove is in the list, you can trivially remove it by removing it from this list.

+1
source

Source: https://habr.com/ru/post/1398157/


All Articles