2010-06-21 4 views
2

Я пытаюсь установить значение тэга TIFF Изображение в C# через код, но как-то значения сохраняются после сохранения изображения.Установить значение DPI для Tiff Image в C#

using (var image = new Bitmap(@"c:\newimage.tif")) 
{ 
    uint[] uintArray = { 300, 1}; //Setting DPI as 300 
    byte[] bothArray = ConvertUintArrayToByteArray(uintArray); 
    PropertyItem item = image.PropertyItems.Where(p => p.Id == 0x11A).Single(); 
    var val = BitConverter.ToUInt32(item.Value, 0); 
    Console.WriteLine(val); 
    item.Id = 0x11A; 
    item.Value = bothArray; 
    item.Type = 5; 
    item.Len = item.Value.Length; 
    image.SetPropertyItem(item); 
    image.Save(@"c:\newimage1.tif"); //Save image to new File 
} 

Что не так с этим кодом? Любая помощь будет оценена по достоинству. TIFF file tag definitions

ответ

3

Я подозреваю, что разрешение битмапа переопределит свойство. Используйте Bitmap.SetResolution().

+0

Я попытался с помощью 'SetResolution()', но до сих пор нет радости :( –

-1

отказ от ответственности: я работаю для Atalasoft, что делает продукты для работы с изображениями через .NET.

Вы можете сделать это dotImage используя класс TiffDocument с кодом, как это:

private void RemoveIfContains(TiffTagCollection tags, int tagID) 
{ 
    TiffTag tag = tags.LookupTag(tagID); 
    if (tag != null) 
     tags.Remove(tag); 
} 

public void SetTiffResolution(string tiffin, string tiffout, int page, double resolution) { 
    if (tiffin == tiffout) 
     throw new ArgumentException(tiffout, "output path must be different from input path"); 
    TiffFile tf = new TiffFile(); 
    using (FileStream stm = new FileStream(tiffin, FileMode.Open, FileAccess.Read, FileShare.Read)) { 
     tf.Read(stm); 
     TiffDirectory image = tf.Images[page]; 
     RemoveIfContains(image.Tags, TiffTagID.ResolutionX); 
     RemoveIfContains(image.Tags, TiffTagID.ResolutionY); 
     RemoveIfContains(image.Tags, TiffTagID.ResolutionUnit); 
     image.Tags.Add(new TiffTag(TiffTagID.ResolutionX, resolution); 
     image.Tags.Add(new TiffTag(TiffTagID.ResolutionY, resolution); 
     image.Tags.Add(new TiffTag(TiffTagID.ResolutionUnit, 2)); // 2 == dots per INCH 
     tf.Save(tiffout); 
    } 
}   

Преимущество несколько - прямой доступ к тегам позволяет установить вещи так, как вы хотите без повторного кодирования изображения , Если ваше исходное изображение было сжато с помощью JPEG внутри TIFF, вам не нужно беспокоиться о проблемах с повторным кодированием данных JPEG и потерей информации. Кроме того, вам не нужно беспокоиться о потере информации тегов TIFF, которая уже была там. Этот код также работает с многостраничными TIFF. Наконец, это, вероятно, будет более быстрый подход, чем декодирование всего изображения, только для изменения тега.

Недостатком такого подхода является то, что вам действительно нужно понять спецификацию TIFF. Без этого понимания вы рискуете создавать файлы, которые могут не всегда обрабатываться. Например, DotImage и IrfanView очень мягко потребляют всевозможные сломанные TIFF. Adobe PhotoShop, как известно, является строгим.

+4

я получаю болен Atalasoft вопиет рекламу через ответные сообщения на StackOverflow (и вы, и Lou Franco). Если вы должны рекламировать здесь покупку фактической рекламы. – 2010-06-21 18:41:24

5

Установка значения свойства и разрешения растрового изображения и последующего сохранения изображения должна изменить разрешение (оно работало на моем образце). Я считаю, что исходный файл должен иметь теги для разрешения X и Y, но не уверен, что .NET добавит эти теги, если они не присутствуют (придется тестировать).

Вот пример чтения и записи X и Y разрешением в формате TIFF изображений с использованием .NET:

int numerator, denominator; 

using (Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\input.tif")) 
{ 
    // obtain the XResolution and YResolution TIFFTAG values 
    PropertyItem piXRes = bmp.GetPropertyItem(282); 
    PropertyItem piYRes = bmp.GetPropertyItem(283); 

    // values are stored as a rational number - numerator/denominator pair 
    numerator = BitConverter.ToInt32(piXRes.Value, 0); 
    denominator = BitConverter.ToInt32(piXRes.Value, 4); 
    float xRes = numerator/denominator; 

    numerator = BitConverter.ToInt32(piYRes.Value, 0); 
    denominator = BitConverter.ToInt32(piYRes.Value, 4); 
    float yRes = numerator/denominator; 

    // now set the values 
    byte[] numeratorBytes = new byte[4]; 
    byte[] denominatorBytes = new byte[4]; 

    numeratorBytes = BitConverter.GetBytes(600); // specify resolution in numerator 
    denominatorBytes = BitConverter.GetBytes(1); 

    Array.Copy(numeratorBytes, 0, piXRes.Value, 0, 4); // set the XResolution value 
    Array.Copy(denominatorBytes, 0, piXRes.Value, 4, 4); 

    Array.Copy(numeratorBytes, 0, piYRes.Value, 0, 4); // set the YResolution value 
    Array.Copy(denominatorBytes, 0, piYRes.Value, 4, 4); 

    bmp.SetPropertyItem(piXRes); // finally set the image property resolution 
    bmp.SetPropertyItem(piYRes); 

    bmp.SetResolution(600, 600); // now set the bitmap resolution 

    bmp.Save(@"C:\output.tif"); // save the image 
}