public TiffImage(string path) { using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { Header = new FileHeader(stream); var offset = Header.Offset; var ifds = new List <ImageFileDirectory>(); while (offset != 0) { stream.Position = offset; var newIfd = new ImageFileDirectory(stream); offset = newIfd.Offset; ifds.Add(newIfd); } IFDs = ifds.ToArray(); var photometricInterpretation = (PhotometricInterpretation)(ushort)ifds[0].Tags.Where(a => a.Code == Tag.TagCode.PhotometricInterpretation).FirstOrDefault().Data; switch (photometricInterpretation) { case PhotometricInterpretation.RGB: ReadRGB(stream); break; case PhotometricInterpretation.Separated: var samples = ifds[0].Tags.FirstOrDefault(a => a.Code == Tag.TagCode.SamplesPerPixel); if (samples == null) { throw new ArgumentException("The given files does not specify a number of samples per pixel."); } Channels = (int)samples.Value; ReadSeparated(stream); break; } } }
private bool SaveRGB(string path) { try { DataStructure = ImageDataStructure.Rgb; using (var stream = new FileStream(path, FileMode.Create)) { var header = new FileHeader() { ByteOrder = FileHeader.TiffByteOrder.II, Offset = 8 }; header.Write(stream); var ifd = new ImageFileDirectory() { Tags = new List <Tag>() { new Tag() { Code = Tag.TagCode.NewSubfileType, Data = 0, DataType = Tag.TagType.Long, Count = 1, Value = 0 }, new Tag() { Code = Tag.TagCode.ImageWidth, Data = (ushort)Width, DataType = Tag.TagType.Short, Count = 1, Value = (ushort)Width }, new Tag() { Code = Tag.TagCode.ImageLength, Data = (ushort)Height, DataType = Tag.TagType.Short, Count = 1, Value = (ushort)Height }, new Tag() { Code = Tag.TagCode.BitsPerSample, Data = new ushort[] { 8, 8, 8 }, DataType = Tag.TagType.Short, Count = 3, Value = 0 }, new Tag() { Code = Tag.TagCode.Compression, Data = (ushort)Tag.CompressionType.None, DataType = Tag.TagType.Short, Count = 1, Value = (uint)Tag.CompressionType.None }, new Tag() { Code = Tag.TagCode.PhotometricInterpretation, Data = PhotometricInterpretation.RGB, DataType = Tag.TagType.Short, Count = 1, Value = (uint)PhotometricInterpretation.RGB }, new Tag() { Code = Tag.TagCode.StripOffsets, Data = 0, DataType = Tag.TagType.Long, Count = 1, Value = 0 }, new Tag() { Code = Tag.TagCode.Orientation, Data = (ushort)1, DataType = Tag.TagType.Short, Count = 1, Value = 1 }, new Tag() { Code = Tag.TagCode.SamplesPerPixel, Count = 1, Data = (ushort)3, DataType = Tag.TagType.Short, Value = 3 }, new Tag() { Code = Tag.TagCode.RowsPerStrip, Data = (ushort)Height, DataType = Tag.TagType.Short, Count = 1, Value = (ushort)Height }, new Tag() { Code = Tag.TagCode.StripByteCounts, Data = (uint)Height * 3, DataType = Tag.TagType.Long, Count = 1, Value = (uint)Height * 3 }, new Tag() { Code = Tag.TagCode.XResolution, Count = 1, Data = 360f, DataType = Tag.TagType.Rational }, new Tag() { Code = Tag.TagCode.YResolution, Count = 1, Data = 360f, DataType = Tag.TagType.Rational }, new Tag() { Code = Tag.TagCode.PlanarConfiguration, Data = PlanarConfiguration.Chunky, DataType = Tag.TagType.Short, Count = 1, Value = (uint)PlanarConfiguration.Chunky }, new Tag() { Code = Tag.TagCode.ResolutionUnit, Count = 1, Data = (ushort)2, DataType = Tag.TagType.Short, Value = (ushort)2 } } }; var tagsOffset = header.ByteCount + ifd.ByteCount; var tagDataCount = 0; foreach (var item in ifd.Tags) { tagDataCount += item.DataSize; } var stripsTag = ifd.Tags.FirstOrDefault(a => a.Code == Tag.TagCode.StripOffsets); stripsTag.Value = (uint)(tagsOffset + tagDataCount); ifd.Write(stream, tagsOffset); stream.Write(Data, 0, Data.Length); } } catch (Exception) { return(false); } return(true); }