public void Save(Stream stream, string format) { // Select a default format for the save. if (format == null) { format = Png; } // Determine how to save the image. if (format == Bmp) { // Windows bitmap image. BmpWriter.Save(stream, this); } else if (format == Icon) { // Windows icon image. IconWriter.Save(stream, this, false); } else if (format == Cursor) { // Windows cursor image (same as icon, with hotspots). IconWriter.Save(stream, this, true); } else if (format == Png) { // PNG image. PngWriter.Save(stream, this); } else if (format == Gif) { // GIF image. If the image is RGB, then we encode // as a PNG instead and hope that the image viewer // is smart enough to check the magic number before // decoding the image. if (GifWriter.IsGifEncodable(this)) { GifWriter.Save(stream, this); } else { PngWriter.Save(stream, this); } } else if (format == Jpeg) { // JPEG image. //JpegWriter.Save(stream, this); // TODO: implement portable jpeg throw new NotImplementedException("PORTABLE JPEG IS NOT YET IMPLEMENTED"); } }
// Save a Windows icon image to the specified stream. If "hotspots" // is "true", then the image is actually a Windows cursor with hotspots. public static void Save(Stream stream, PortableImage image, bool hotspots) { byte[] buffer = new byte [1024]; int numImages = image.NumFrames; int offset, index, size, bitCount; int[] offsetList; int[] sizeList; Frame frame; // Write the image header. buffer[0] = 0; buffer[1] = 0; buffer[2] = (byte)(hotspots ? 2 : 1); buffer[3] = 0; Utils.WriteUInt16(buffer, 4, numImages); stream.Write(buffer, 0, 6); // Infer the starting offsets and sizes for each of the images. offset = 6 + numImages * 16; offsetList = new int [numImages]; sizeList = new int [numImages]; for (index = 0; index < numImages; ++index) { frame = image.GetFrame(index); size = 40; if ((frame.pixelFormat & PixelFormat.Indexed) != 0) { size += 4 * (1 << Utils.FormatToBitCount(frame.pixelFormat)); } size += frame.Height * (frame.Stride + frame.MaskStride); offsetList[index] = offset; sizeList[index] = size; offset += size; } // Write the contents of the resource directory. for (index = 0; index < image.NumFrames; ++index) { frame = image.GetFrame(index); bitCount = Utils.FormatToBitCount(frame.pixelFormat); buffer[0] = (byte)(frame.Width); buffer[1] = (byte)(frame.Height); buffer[2] = (byte)(1 << bitCount); buffer[3] = 0; if (hotspots) { Utils.WriteUInt16(buffer, 4, frame.HotspotX); Utils.WriteUInt16(buffer, 6, frame.HotspotY); } else { Utils.WriteUInt16(buffer, 4, 0); Utils.WriteUInt16(buffer, 6, 0); } Utils.WriteInt32(buffer, 8, sizeList[index]); Utils.WriteInt32(buffer, 12, offsetList[index]); stream.Write(buffer, 0, 16); } // Write each of the images. for (index = 0; index < image.NumFrames; ++index) { frame = image.GetFrame(index); bitCount = Utils.FormatToBitCount(frame.pixelFormat); BmpWriter.SaveBitmapInfo (stream, frame, bitCount, (frame.Stride + frame.MaskStride) * frame.Height, buffer, frame.Height * 2); BmpWriter.SaveBitmapData(stream, frame, false, false); BmpWriter.SaveBitmapData(stream, frame, true, true); } }