在C#中将DPI值设置为Tiff图像

时间:2010-06-21 12:44:55

标签: c# image-processing tiff

我正在尝试通过代码在C#中设置TIFF图像的dpi值,但不知何故,在保存图像后值不会保留。

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 个答案:

答案 0 :(得分:5)

设置属性值和位图分辨率,然后重新保存图像应该改变分辨率(它适用于我的样本图像)。我相信原始文件必须包含X和Y分辨率的标签,不确定.NET是否会添加这些标签(如果不存在)(必须进行测试)。

以下是使用.NET读取和写入TIFF图像的X和Y分辨率的示例:

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
}

答案 1 :(得分:3)

我怀疑Bitmap分辨率会覆盖该属性。使用Bitmap.SetResolution()。

答案 2 :(得分:-1)

免责声明:我为Atalasoft工作,该公司生产用于通过.NET处理图像的产品。

你可以使用TiffDocument类使用这样的代码来执行这个dotImage:

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);
    }
}           

优点有几个 - 直接访问标签可让您按照自己的方式设置,而无需重新编码图像。如果在TIFF中使用JPEG压缩初始图像,则无需担心重新编码JPEG数据和丢失信息的问题。此外,您不必担心丢失已存在的TIFF标记信息。此代码也适用于多页TIFF。最后,这可能比解码整个图像只是为了更改标签更快。

这种方法的缺点是你真的需要了解TIFF规范。如果没有这种理解,您就有可能创建可能并不总是可解析的文件。例如,DotImage和IrfanView在消费各种破坏的TIFF方面非常宽容。 Adobe PhotoShop是出了名的严格。