/// <summary> /// Writes the image data into the stream in the given format. /// </summary> /// <param name="image">The image whose data to write.</param> /// <param name="stream">The stream into which to write the data.</param> /// <param name="type">The type of Netpbm image according to which to encode the data.</param> /// <typeparam name="TPixelComponent">The type of pixel component values.</typeparam> public void WriteImageData <TPixelComponent>(NetpbmImage <TPixelComponent> image, Stream stream, ImageType type) { // check if the format is supported var supportedTypes = SupportedTypesForImage(image); if (!supportedTypes.Contains(type)) { throw new ArgumentOutOfRangeException("type", type, "the image cannot be encoded into this type"); } using (var writer = new NetpbmBinaryWriter(stream, new UTF8Encoding(false, true), leaveOpen: true)) { bool isPlain; switch (type) { case ImageType.PBM: case ImageType.PGM: case ImageType.PPM: case ImageType.PAM: case ImageType.BigPAM: isPlain = false; break; case ImageType.PlainPBM: case ImageType.PlainPGM: case ImageType.PlainPPM: isPlain = true; break; default: throw new ArgumentOutOfRangeException("type", type, "unknown image type"); } if (isPlain) { // output in row-major order as decimal numbers // add newlines after each row to make things nicer foreach (var row in image.NativeRows) { foreach (var value in row) { writer.WriteUnprefixed(value.ToString()); writer.Write(' '); } writer.Write('\n'); } } else if (type == ImageType.PBM) { // special case: bit-packed format! var values = new List <TPixelComponent>(8); foreach (var row in image.NativeRows) { foreach (var value in row) { values.Add(value); if (values.Count == 8) { byte theByte = EncodeBitmapValuesIntoByte(image, values); writer.Write(theByte); values.Clear(); } } if (values.Count != 0) { byte theByte = EncodeBitmapValuesIntoByte(image, values); writer.Write(theByte); } } } else { // just the big endian bytes foreach (var row in image.NativeRows) { foreach (var value in row) { writer.Write(image.ComponentToBigEndianBytes(value).ToArray()); } } } } }
/// <summary> /// Writes a row of image data into the stream in the given format. /// </summary> /// <param name="image">The image whose row is being encoded (for formatting purposes).</param> /// <param name="row">The row to write.</param> /// <param name="stream">The stream to write into.</param> /// <param name="type">The format according to which to write.</param> public void WriteImageRow <TPixelComponent>(NetpbmImage <TPixelComponent> image, IEnumerable <TPixelComponent> row, Stream stream, ImageType type) { using (var writer = new NetpbmBinaryWriter(stream, new UTF8Encoding(false, true), leaveOpen: true)) { bool isPlain; switch (type) { case ImageType.PBM: case ImageType.PGM: case ImageType.PPM: case ImageType.PAM: case ImageType.BigPAM: isPlain = false; break; case ImageType.PlainPBM: case ImageType.PlainPGM: case ImageType.PlainPPM: isPlain = true; break; default: throw new ArgumentOutOfRangeException("type", type, "unknown image type"); } if (isPlain) { // output row as decimal numbers // add a newline after the row to make things nicer foreach (var value in row) { writer.WriteUnprefixed(value.ToString()); writer.Write(' '); } writer.Write('\n'); } else if (type == ImageType.PBM) { // special case: bit-packed format! var values = new List <TPixelComponent>(8); foreach (var value in row) { values.Add(value); if (values.Count == 8) { byte theByte = EncodeBitmapValuesIntoByte(image, values); writer.Write(theByte); values.Clear(); } } if (values.Count != 0) { byte theByte = EncodeBitmapValuesIntoByte(image, values); writer.Write(theByte); } } else { // just the big endian bytes foreach (var value in row) { writer.Write(image.ComponentToBigEndianBytes(value).ToArray()); } } } }
/// <summary> /// Writes the image header into the stream in the given format. /// </summary> /// <param name="header">The image header to write.</param> /// <param name="stream">The stream into which to write the header.</param> /// <param name="type">The type of Netpbm image according to which to encode the header.</param> /// <typeparam name="TPixelComponent">The type of pixel component values.</typeparam> public void WriteImageHeader <TPixelComponent>(NetpbmHeader <TPixelComponent> header, Stream stream, ImageType type) { // check if the format is supported var supportedTypes = SupportedTypesForHeader(header); if (!supportedTypes.Contains(type)) { throw new ArgumentOutOfRangeException("type", type, "the image cannot be encoded into this type"); } using (var writer = new NetpbmBinaryWriter(stream, new UTF8Encoding(false, true), leaveOpen: true)) { int magicNumber = (int)type; switch (type) { case ImageType.PBM: case ImageType.PGM: case ImageType.PPM: case ImageType.PAM: case ImageType.PlainPBM: case ImageType.PlainPGM: case ImageType.PlainPPM: break; case ImageType.BigPAM: magicNumber = (int)ImageType.PAM; break; default: throw new ArgumentOutOfRangeException("type", type, "unknown image type"); } // output the magic writer.WriteUnprefixed("P{0}\n", magicNumber); if (type == ImageType.PAM || type == ImageType.BigPAM) { // output width line writer.WriteUnprefixed("WIDTH {0}\n", header.Width); // output height line writer.WriteUnprefixed("HEIGHT {0}\n", header.Height); // output number of components writer.WriteUnprefixed("DEPTH {0}\n", header.Components.Count); // maximum value writer.WriteUnprefixed("MAXVAL {0}\n", header.HighestComponentValue); // find the components we are working with writer.WriteUnprefixed("TUPLTYPE {0}\n", GetPamTupleType(header)); writer.WriteUnprefixed("ENDHDR\n"); } else { // output width and height writer.WriteUnprefixed("{0} {1}\n", header.Width, header.Height); // unless PBM (where the max value is always 1) if (type != ImageType.PBM && type != ImageType.PlainPBM) { // output the max value writer.WriteUnprefixed("{0}\n", header.HighestComponentValue); } // the header's final newline writer.Write('\n'); } } }