.NET Framework - TiffBitmapEncoder bug?

Asked By Robert Simpson
24-May-07 06:58 PM
I've finally nailed down a problem with some TIFF's I've been generating in
.NET, and wanted to know where the blame may lay :)

I have some pretty simple code which saves a TIFF in Ccitt3 format.
However, when opening the resulting TIFF in something like Paint Shop Pro X
(as well as some other 3rd party viewers), the image is completely distorted
and horizontal bars appear all over the page.

I did some digging, and ran LIBTIFF's "tiffinfo" program against the TIFF's
coming out of my program.  Invariably, tiffinfo complained "Bad value 0 for

Upon further research, I read in the TIFF spec:

-----
FillOrder
The logical order of bits within a byte.
Tag = 266 (10A.H)
Type = SHORT
N = 1
1 = pixels are arranged within a byte such that pixels with lower column
values are
stored in the higher-order bits of the byte.

2 = pixels are arranged within a byte such that pixels with lower column
values are
stored in the lower-order bits of the byte.
-----

As you can see, there is no "0" value documented.

I went into the binary file and manually altered the FillOrder field in the
TIFF to change it from 0 to 1, and viola -- PSP X and the other 3rd party
viewers were magically able to open and view my TIFF without any issues.

So ... my question(s) are:
I never set the fillorder, and I expect the TiffBitmapEncoder to do so ...
my saving method is nothing more than:

TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Ccitt3;
BitmapFrame frame = BitmapFrame.Create(target);
encoder.Frames.Add(frame);
using (FileStream fs2 = new FileStream("c:\\out.tif", FileMode.Create,
FileAccess.ReadWrite, FileShare.Read))
{
encoder.Save(fs2);
}

I even tried setting the fillorder progammatically with:

using (FileStream fs2 = new FileStream("c:\\out.tif", FileMode.Open,
FileAccess.ReadWrite, FileShare.Read))
{
decoder = new TiffBitmapDecoder(fs2,
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
InPlaceBitmapMetadataWriter inmeta =
decoder.Frames[0].CreateInPlaceBitmapMetadataWriter();
if (inmeta.TrySave())
{
inmeta.SetQuery("/ifd/{short=266}", 1);
}
}

... but this didn't work.  So what gives?  For now I've resorted to opening
the file stream after saving, reading the TIFF header, and rewriting the
FillOrder tag myself.

Robert
InPlaceBitmapMetadataWriter
(1)
CreateInPlaceBitmapMetadataWriter
(1)
TiffBitmapEncoder
(1)
BitmapCreateOptions
(1)
TiffCompressOption
(1)
BitmapCacheOption
(1)
TiffBitmapDecoder
(1)
FileStream
(1)
  Andrew Christiansen replied...
28-May-07 09:17 PM
Strange the encoder writes the FillOrder field unset.  My answer was going
to be the same as what you have resorted to, opening the image after saving,
seek the position of the offending FillOrder field, and use
BinaryWriter.Write(Convert.ToInt16(1));.

Andrew
  Robert A. Wlodarczyk replied...
19-Jul-07 01:17 AM
I noticed that you had some problems with the InPlaceBitmapMetadataWriter. You may be interested in a new sample that I posted: http://blogs.msdn.com/rwlodarc/archive/2007/07/18/using-wpf-s-inplacebitmapmetadatawriter.aspx
The sample is for JPEG, but can easily be modified for TIFFs.
Create New Account
help
with this please Thanks in advance Roger ASP.NET Discussions BitmapCreateOptions.PreservePixelFormat (1) CreateInPlaceBitmapMetadataWriter (1) InPlaceBitmapMetadataWriter (1) System.IO.FileStream (1) JpgFrame.CreateInPlaceBitmapMetadataWriter (1) BitmapCacheOption.Default (1) FileAccess.ReadWrite (1) FileShare ReadWrite); JpegBitmapDecoder jpgDecoder = new JpegBitmapDecoder(jpgStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); BitmapFrame jpgFrame = jpgDecoder.Frames[0]; InPlaceBitmapMetadataWriter jpgInplace = jpgFrame.CreateInPlaceBitmapMetadataWriter(); if (jpgInplace.TrySave() = = true) { jpgInplace.SetQuery(" / Text / Title", "Have a nice day
with the colors Black and White 7. Setting the DestinationFormat to Indexed1 8. Constructing a TiffBitmapEncoder and setting it's compression to LZO. 9. Saving the file. Here is my sample newBmpSource.Source = bmpSource; newBmpSource.DestinationPalette = palette; newBmpSource.DestinationFormat = System.Windows.Media.PixelFormats.Indexed1; newBmpSource.EndInit(); TiffBitmapEncoder tiffEncoder = new TiffBitmapEncoder(); tiffEncoder.Compression = TiffCompressOption.Lzw; tiffEncoder.Frames.Add(BitmapFrame.Create(newBmpSource)); using(FileStream fs = new FileStream
1) Visual Studio 2005 (1) System.IO.Stream (1) PixelFormat.Format32bppArgb (1) SmoothingMode.AntiAlias (1) TiffBitmapEncoder (1) Office 2007 (1) Du könntest, falls vorhanden, den XPS-Drucker auswählen und anschließend auf page" + (count++).ToString() + ".bmp"); } bmp.Dispose(); } _ __ __ __ __ __ _ Für XPS, TIF zum Beispiel über das XpsDocument, TiffBitmapEncoder: [XpsDocument-Klasse (System.Windows.Xps.Packaging)] http: / / msdn.microsoft.com / de-de / library / system.windows.xps.packaging.xpsdocument.aspx [TiffBitmapEncoder-Klasse (System.Windows.Media.Imaging)] http: / / msdn.microsoft.com / de-de / library / system.windows.media imaging.tiffbitmapencoder.aspx ciao Frank - - Dipl.Inf. Frank Dzaebel [MCP / MVP C#] http: / / Dzaebel.NET Hallo Frank, wie kann ich die XpsDocument-Klasse bzw. die TiffBitmapEncoder in mein Projekt ein binden. Bei mir kommt nach "System.Windows." nur noch Forms zur de-de / library / ms771722.aspx Tiff ggf.: [Overwriting frames selectively in a tiff file using TiffBitMapEncoder : Windows Imaging Component (WIC) : Software Development for Windows Client : MSDN Forums] http: / / social.msdn.microsoft
laden, ist Hat jemand eine Idee für mich bitte? Gruß Andy VB.NET - German Discussions InPlaceBitmapMetadataWriter (1) JpegImage.GetPropertyItem (1) System.Windows.Freezable (1) File.ReadAllBytes (1) BitmapFrame.Metadata (1) BitmapFrame Falls Du nur (möglichst schnell) die Metadaten ändern willst, kannst Du vermutlich auf die Klasse InPlaceBitmapMetadataWriter zurückgreifen (ungeprüft). Gruß Joachim - - Dr. Joachim Fuchs - Autor - Dozent - Softwarearchitekt http: / / www.fuechse-online.de _Frame as BitmapFrame kommt die von mir beschriebene Fehlermeldung bzw. der Hinweis. Auch wenn ich InPlaceBitmapMetadataWriter nehmen möchte. Gleiche Meldung. Ich soll einen Verweis hinzufügen der System.Windows.Freezable enthält. Und