2012-02-24 18 views
4

我似乎無法找到任何有關如何使用LibTiff.Net庫刪除tiff標籤的文檔。我喜歡圖書館,但這種方法對於我需要做的事很重要。有一次,我希望能夠設置一個標籤並將其設置爲無價值。我曾希望這會起作用,但這是一個消極的。如何使用LibTiff.Net 2.3庫刪除tiff標籤

任何人都知道如何使用LibTiff.Net庫刪除tiff標籤?

回答

1

注意:首先這可能看起來像一個很大的答案,但我想確保看到這個人的所有「我創建的專有類,以保持一切裝箱清潔。答案儘可能的排序和提供信息我只會粘貼DeleteTiffTags方法的代碼,其餘的代碼可以通過here下載

現在談談好東西......我最終花了大約這一切都可以歸功於各種各樣的問題,我們在我的一個類中寫了兩個小的(非常詳細的)方法來刪除一個tiff標籤,第一個是爲了刪除一個列表給定標籤,第二個是t o刪除一個用於提及方法的標籤。同樣在這個例子中,我添加了幾行來支持我的自定義tiff標籤......它們都將以// ADDED註釋開頭。

類:

公共靜態類TIFFTAGS - 這個類是簡單地做這樣的事情TIFFTAGS.DeleteTiffTags()稱爲主階層;由於它是一個靜態類 ,因此不需要創建它的一個對象來使用它的方法。

私人課TIFFTAGS_PAGE - 此課是一個私人類,它位於TIFFTAGS類內。它的目的是包含可能在tiff中的所有頁面的所有單頁信息。它是私人的,只用於 內部用途。

公共課TIFFTAGS_TAG - 這是我爲了更好地包裝標籤而設計的一個類。使用標準標籤類型名稱,例如ASCII,SHORT,LONG, 和RATIONAL。

方法/函數:

TagExtender() - 這個小寶石是一個回調函數,可以讓你真正使您的自定義標籤的TIFF。沒有它,當您刪除任何標籤時(即使您只刪除了 之一),您的所有自定義標籤 都會消失。

DeleteTiffTags() - 這是刪除標籤列表的主要方法。只需傳入一個ushort標籤號碼列表,全部將被刪除。請記住, 未使用TagExtender功能會導致您的自定義標籤去 poof

DeleteTiffTag() - 這只是用來刪除一個tiff標籤。它調用DeleteTiffTags()來處理繁瑣的工作。

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's 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

我想你將不得不基本上覆制輸入文件到一個新的TIFF圖像過濾出你不想在過程中的標籤。查看屬於常規libtiff分發的一部分的tiffcp實用程序。它有點這樣做,減去過濾。

聲明:我從來沒有使用LibTiff.Net,並假設它與LibTiff非常相似。

看一看tiffcp.c

首先,它手動拷貝/設置了一些公知的標記,如分辨率,壓縮,顏色等 然後它將所有的一組可以被複制的w/o預處理標籤:

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

然後它複製實際的像素數據。根據我的記錄,刪除任何tiffcp未知的標籤。如果您要刪除的代碼位於列表中,則可以通過將其從列表中刪除來簡單地刪除它。

+0

「過濾」部分是關鍵。我不知道我會怎麼做。看着tiffcp.exe,它似乎只是簡單地複製與不同類型的壓縮等tiff。 – 2012-02-24 02:33:20

+0

你應該看的源代碼,而不是exe?我已經用一些細節更新了上面的答案。 – 2012-02-24 03:26:36

+0

感謝MK,我正在研究C#代碼。找到與您在c中發佈的相似的區域。有時間去挖掘它。 ;) – 2012-02-24 18:21:05

3

請看一下LibTiff.Net附帶的TiffCP工具(尤其是它的源代碼)。

LibTiff.Net不提供刪除標籤的方法(LibTiff也是如此)。您將需要實現TiffCP功能的零件以實現此目的。

基本上,你需要複製你想保留的所有標籤,並且複製像素數據而不需要解碼並重新編碼它。

也請看看Convert a multi-strip TIFF image to a single-strip one樣本。它顯示瞭如何複製標籤並將原始(未解碼的數據)從一個圖像複製到另一個圖像。該示例在某些情況下實際解碼數據,因爲它需要更改條數,但不需要解碼數據。

+0

哇!這看起來正是我所追求的。我寧願處理暴露的方法,然後挖掘到私人方法。感謝一幫人指出了Bobrovsky!我剛剛獲得了「投票」特權......猜猜我會在哪裏使用我的第一票? ;) – 2012-02-24 18:26:20