// Set the dgImage field within this object. internal void SetDGImage(DotGNU.Images.Image dgImage) { flags = 0; #if !ECMA_COMPAT switch (dgImage.LoadFormat) { case DotGNU.Images.Image.Png: rawFormat = ImageFormat.Png; break; case DotGNU.Images.Image.Jpeg: rawFormat = ImageFormat.Jpeg; break; case DotGNU.Images.Image.Gif: rawFormat = ImageFormat.Gif; break; case DotGNU.Images.Image.Tiff: rawFormat = ImageFormat.Tiff; break; case DotGNU.Images.Image.Bmp: rawFormat = ImageFormat.Bmp; break; case DotGNU.Images.Image.Icon: rawFormat = ImageFormat.Icon; break; case DotGNU.Images.Image.Exif: rawFormat = ImageFormat.Exif; break; } frameDimensionsList = new Guid [0]; this.dgImage = dgImage; // If we are loading an icon, set the size of the image // to the size of the first icon if (rawFormat == ImageFormat.Icon || rawFormat == ImageFormat.Gif) { width = dgImage.GetFrame(0).Width; height = dgImage.GetFrame(0).Height; } else { width = dgImage.Width; height = dgImage.Height; } #else this.dgImage = dgImage; width = dgImage.GetFrame(0).Width; height = dgImage.GetFrame(0).Height; #endif horizontalResolution = Graphics.DefaultScreenDpi; verticalResolution = Graphics.DefaultScreenDpi; pixelFormat = (System.Drawing.Imaging.PixelFormat) (dgImage.PixelFormat); }
// Draw the source parallelogram of an image into the parallelogram // defined by dest. Point[] has 3 Points, Top-Left, Top-Right and Bottom-Left. // The remaining point is inferred. public virtual void DrawImage(IToolkitImage image, Point[] src, Point[] dest) { int originX = dest[0].X; int originY = dest[0].Y; for (int i = 1; i < 3; i++) { if (originX > dest[i].X) { originX = dest[i].X; } if (originY > dest[i].Y) { originY = dest[i].Y; } } DotGNU.Images.Image gnuImage = (image as ToolkitImageBase).image; // Currently we only draw the first frame. Frame frame = gnuImage.GetFrame(0); frame = frame.AdjustImage(src[0].X, src[0].Y, src[1].X, src[1].Y, src[2].X, src[2].Y, dest[0].X - originX, dest[0].Y - originY, dest[1].X - originX, dest[1].Y - originY, dest[2].X - originX, dest[2].Y - originY); // Setup the new image and draw it. using (DotGNU.Images.Image newGnuImage = new DotGNU.Images.Image(gnuImage.Width, gnuImage.Height, gnuImage.PixelFormat)) { newGnuImage.AddFrame(frame); IToolkitImage newImage = Toolkit.CreateImage(newGnuImage, 0); DrawImage(newImage, originX, originY); } }
// Determine if an image only has indexed frames in it and // that all frames have the same pixel format. public static bool IsGifEncodable(Image image) { int index; Frame frame; PixelFormat format = (PixelFormat)(-1); if (image.NumFrames == 0) { return(false); } for (index = 0; index < image.NumFrames; ++index) { frame = image.GetFrame(index); if ((frame.PixelFormat & PixelFormat.Indexed) == 0) { return(false); } if (format != (PixelFormat)(-1) && format != frame.PixelFormat) { return(false); } format = frame.PixelFormat; } return(true); }
// Load the icon contents from a stream, and then set the // current frame to the first one in the icon image. private void Load(Stream stream) { image = new DotGNU.Images.Image(); image.Load(stream); frame = image.GetFrame(0); frameNum = 0; }
/// <summary> /// <para>Constructs a new <see cref="T:Xsharp.Image"/> instance /// that represents an off-screen image that was loaded /// from a file.</para> /// </summary> /// /// <param name="screen"> /// <para>The screen upon which to create the new pixmap.</para> /// </param> /// /// <param name="filename"> /// <para>The file to load the image from.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>The <paramref name="filename"/> parameter is /// <see langword="null"/>.</para> /// </exception> /// /// <exception cref="T:System.FormatException"> /// <para>The image format is not recognized.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="filename"/> could not be /// loaded for some reason.</para> /// </exception> public Image(Screen screen, String filename) { Display dpy; if (filename == null) { throw new ArgumentNullException("filename"); } if (screen != null) { dpy = screen.DisplayOfScreen; } else { dpy = Application.Primary.Display; screen = dpy.DefaultScreenOfDisplay; } this.screen = screen; DotGNU.Images.Image img = new DotGNU.Images.Image(); img.Load(filename); Frame frame = img.GetFrame(0); try { dpy.Lock(); pixmapXImage = ConvertImage.FrameToXImage(screen, frame); maskXImage = ConvertImage.MaskToXImage(screen, frame); } finally { dpy.Unlock(); } }
// This is an internal member and should not be used. // Returns a bitmap which is the resized (to newWidth and newHeight) of the first frame. public Image Resize(int newWidth, int newHeight) { Frame frame = dgImage.GetFrame(0); Frame newFrame = frame.AdjustImage(0, 0, width, 0, 0, height, 0, 0, newWidth, 0, 0, newHeight); DotGNU.Images.Image newImage = new DotGNU.Images.Image(newWidth, newHeight, newFrame.PixelFormat); newImage.AddFrame(newFrame); return(new Bitmap(newImage)); }
// Select a particular frame from this icon. private void SelectFrame(int width, int height) { int index; Frame frame; for (index = 0; index < image.NumFrames; ++index) { frame = image.GetFrame(index); if (frame.Width == width && frame.Height == height) { this.frame = frame; frameNum = index; return; } } frame = image.GetFrame(0); frameNum = 0; }
private Icon(Icon cloneFrom) { if (cloneFrom == null) { throw new ArgumentNullException("cloneFrom"); } image = (DotGNU.Images.Image)(cloneFrom.image.Clone()); frameNum = cloneFrom.frameNum; frame = image.GetFrame(frameNum); }
// Copy image into this.image at x, y public override void DrawImage(IToolkitImage image, int x, int y) { DotGNU.Images.Image sourceImage = (image as ToolkitImageBase).image; Frame sourceFrame = sourceImage.GetFrame(0); DotGNU.Images.Image destImage = this.image.image; Frame destFrame =destImage.GetFrame(0); if (sourceFrame.PixelFormat != destFrame.PixelFormat) sourceFrame = sourceFrame.Reformat(destImage.PixelFormat); destFrame.Copy(sourceFrame, x, y); this.image.ImageChanged(); }
// Save a BMP image to the specified stream. public static void Save(Stream stream, Image image) { byte[] buffer = new byte [1024]; int bitCount; int offset; int size; // We can only save the first frame in BMP formats. Frame frame = image.GetFrame(0); if (frame == null) { return; } // Determine the size of the bitmap and the offset to it. bitCount = Utils.FormatToBitCount(frame.pixelFormat); size = frame.Stride * frame.Height; offset = 14 + 40; if (bitCount <= 8) { offset += (1 << bitCount) * 4; } // Build and write the BITMAPFILEHEADER structure. buffer[0] = (byte)'B'; buffer[1] = (byte)'M'; Utils.WriteInt32(buffer, 2, offset + size); buffer[6] = (byte)0; buffer[7] = (byte)0; buffer[8] = (byte)0; buffer[9] = (byte)0; Utils.WriteInt32(buffer, 10, offset); stream.Write(buffer, 0, 14); // Build and write the BITMAPINFO details. SaveBitmapInfo(stream, frame, bitCount, size, buffer, frame.Height); // Write the bitmap data in the frame to the stream. SaveBitmapData(stream, frame, false, false); }
// Save a BMP image to the specified stream. public static void Save(Stream stream, Image image) { byte[] buffer = new byte [1024]; int bitCount; int offset; int size; // We can only save the first frame in BMP formats. Frame frame = image.GetFrame(0); if(frame == null) { return; } // Determine the size of the bitmap and the offset to it. bitCount = Utils.FormatToBitCount(frame.pixelFormat); size = frame.Stride * frame.Height; offset = 14 + 40; if(bitCount <= 8) { offset += (1 << bitCount) * 4; } // Build and write the BITMAPFILEHEADER structure. buffer[0] = (byte)'B'; buffer[1] = (byte)'M'; Utils.WriteInt32(buffer, 2, offset + size); buffer[6] = (byte)0; buffer[7] = (byte)0; buffer[8] = (byte)0; buffer[9] = (byte)0; Utils.WriteInt32(buffer, 10, offset); stream.Write(buffer, 0, 14); // Build and write the BITMAPINFO details. SaveBitmapInfo(stream, frame, bitCount, size, buffer, frame.Height); // Write the bitmap data in the frame to the stream. SaveBitmapData(stream, frame, false, false); }
private Icon(Icon cloneFrom) { if(cloneFrom == null) { throw new ArgumentNullException("cloneFrom"); } image = (DotGNU.Images.Image)(cloneFrom.image.Clone()); frameNum = cloneFrom.frameNum; frame = image.GetFrame(frameNum); }
// Save a PNG image to the specified stream. public static void Save(Stream stream, Image image) { Frame frame = image.GetFrame(0); byte[] buffer = new byte [1024]; ChunkWriter writer = new ChunkWriter(stream); int colorType, bitDepth; int sigRed, sigGreen, sigBlue, sigAlpha; int paletteSize, posn; int[] palette; ZlibCompressor compressor; ScanlineWriter scanlineWriter; OutputFunc func; int y; // Determine the color type and bit depth for the image. sigRed = -1; sigGreen = -1; sigBlue = -1; sigAlpha = -1; paletteSize = 0; switch(frame.PixelFormat) { case PixelFormat.Format16bppRgb555: { sigRed = 5; sigGreen = 5; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format16bppRgb565: { sigRed = 5; sigGreen = 6; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: { colorType = 2; bitDepth = 8; } break; case PixelFormat.Format1bppIndexed: { colorType = 3; bitDepth = 1; paletteSize = 2; } break; case PixelFormat.Format4bppIndexed: { colorType = 3; bitDepth = 4; paletteSize = 16; } break; case PixelFormat.Format8bppIndexed: { colorType = 3; bitDepth = 8; paletteSize = 256; } break; case PixelFormat.Format16bppArgb1555: { sigRed = 5; sigGreen = 5; sigBlue = 5; sigAlpha = 1; colorType = 6; bitDepth = 8; } break; case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppArgb: { colorType = 6; bitDepth = 8; } break; case PixelFormat.Format16bppGrayScale: { colorType = 0; bitDepth = 16; } break; case PixelFormat.Format48bppRgb: { colorType = 2; bitDepth = 16; } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { colorType = 6; bitDepth = 16; } break; default: throw new FormatException("unknown format"); } // Write out the PNG magic number. stream.Write(magic, 0, magic.Length); // Write the header chunk. Utils.WriteInt32B(buffer, 0, frame.Width); Utils.WriteInt32B(buffer, 4, frame.Height); buffer[8] = (byte)bitDepth; buffer[9] = (byte)colorType; buffer[10] = (byte)0; // Compression method. buffer[11] = (byte)0; // Filter method. buffer[12] = (byte)0; // Interlace method. writer.Write(PngReader.IHDR, buffer, 0, 13); // Write the significant bits chunk if necessary. if(sigAlpha != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; buffer[3] = (byte)sigAlpha; writer.Write(PngReader.sBIT, buffer, 0, 4); } else if(sigRed != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; writer.Write(PngReader.sBIT, buffer, 0, 3); } // Write the palette and transparency chunks. if(paletteSize > 0) { Array.Clear(buffer, 0, buffer.Length); palette = frame.Palette; if(palette != null) { for(posn = 0; posn < palette.Length && posn < paletteSize; ++posn) { buffer[posn * 3] = (byte)(palette[posn] >> 16); buffer[posn * 2 + 1] = (byte)(palette[posn] >> 8); buffer[posn * 2 + 2] = (byte)(palette[posn]); } } writer.Write(PngReader.PLTE, buffer, 0, paletteSize * 3); if(frame.TransparentPixel >= 0 && frame.TransparentPixel < paletteSize) { for(posn = 0; posn < paletteSize; ++posn) { buffer[posn] = (byte)0xFF; } buffer[frame.TransparentPixel] = (byte)0x00; writer.Write(PngReader.tRNS, buffer, 0, frame.TransparentPixel + 1); } } // Compress and write the scanlines to the output stream. compressor = new ZlibCompressor(writer); scanlineWriter = new ScanlineWriter (compressor, frame.Width, frame.PixelFormat); func = GetOutputFunc(frame.PixelFormat); for(y = 0; y < frame.Height; ++y) { func(frame, y, scanlineWriter.Buffer); scanlineWriter.FlushScanline(); } compressor.Finish(); // Write the end chunk. writer.Write(PngReader.IEND, buffer, 0, 0); }
// Load the icon contents from a stream, and then set the // current frame to the first one in the icon image. private void Load(Stream stream) { image = new DotGNU.Images.Image(); image.Load(stream); frame = image.GetFrame(0); frameNum = 0; }
// Save a JPEG image to the specified stream. public static void Save(Stream stream, Image image) { // Determine if we actually have the JPEG library. if (!JpegLib.JpegLibraryPresent()) { throw new FormatException("libjpeg is not available"); } // Create the compression object. JpegLib.jpeg_compress_struct cinfo; cinfo = new JpegLib.jpeg_compress_struct(); cinfo.err = JpegLib.CreateErrorHandler(); JpegLib.jpeg_create_compress(ref cinfo); // Initialize the destination manager. JpegLib.StreamToDestinationManager(ref cinfo, stream); // Get the frame to be written. Frame frame = image.GetFrame(0); // Set the JPEG compression parameters. cinfo.image_width = (UInt)(frame.Width); cinfo.image_height = (UInt)(frame.Height); cinfo.input_components = (Int)3; cinfo.in_color_space = JpegLib.J_COLOR_SPACE.JCS_RGB; JpegLib.jpeg_set_defaults(ref cinfo); // Start the compression process. JpegLib.jpeg_start_compress(ref cinfo, (Int)1); // Write the scanlines to the image. int posn, width, offset, stride; width = frame.Width; stride = frame.Stride; byte[] data = frame.Data; PixelFormat format = frame.PixelFormat; IntPtr buf = Marshal.AllocHGlobal(width * 3); byte * pbuf = (byte *)buf; while (((int)(cinfo.next_scanline)) < ((int)(cinfo.image_height))) { // Convert the source scanline into the JCS_RGB format. offset = ((int)(cinfo.next_scanline)) * stride; switch (format) { case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppArgb1555: { Rgb555(data, offset, width, pbuf); } break; case PixelFormat.Format16bppRgb565: { Rgb565(data, offset, width, pbuf); } break; case PixelFormat.Format24bppRgb: { Rgb24bpp(data, offset, width, pbuf); } break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: { Rgb32bpp(data, offset, width, pbuf); } break; case PixelFormat.Format1bppIndexed: { Rgb1bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format4bppIndexed: { Rgb4bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format8bppIndexed: { Rgb8bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format16bppGrayScale: { GrayScale16bpp(data, offset, width, pbuf); } break; case PixelFormat.Format48bppRgb: { Rgb48bpp(data, offset, width, pbuf); } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { Rgb64bpp(data, offset, width, pbuf); } break; } // Write the scanline to the buffer. JpegLib.jpeg_write_scanlines (ref cinfo, ref buf, (UInt)1); } Marshal.FreeHGlobal(buf); // Finish the compression process. JpegLib.jpeg_finish_compress(ref cinfo); // Clean everything up. JpegLib.FreeDestinationManager(ref cinfo); JpegLib.jpeg_destroy_compress(ref cinfo); JpegLib.FreeErrorHandler(cinfo.err); }
// Save a GIF image to the specified stream. This uses the "ungif" // approach of writing uncompressed code samples to avoid infringing // on the LZW patent. The patent may have expired already, but we // aren't taking any chances. Use PNG instead - it compresses better. public static void Save(Stream stream, Image image) { byte[] buffer = new byte [1024]; Frame frame0, frame; int bitCount, index; int[] palette; // Get the first frame in the image and the image's bit depth. frame0 = image.GetFrame(0); bitCount = Utils.FormatToBitCount(frame0.PixelFormat); // Write the GIF file header. buffer[0] = (byte)'G'; buffer[1] = (byte)'I'; buffer[2] = (byte)'F'; buffer[3] = (byte)'8'; buffer[4] = (byte)'9'; buffer[5] = (byte)'a'; Utils.WriteUInt16(buffer, 6, image.Width); Utils.WriteUInt16(buffer, 8, image.Height); buffer[10] = (byte)((bitCount - 1) | ((bitCount - 1) << 4) | 0x80); if(frame0.TransparentPixel != -1) { // Use the transparent pixel as the background color. buffer[11] = (byte)(frame0.TransparentPixel); } else { // Assume that index zero is the background color. buffer[11] = (byte)0x00; } buffer[12] = (byte)0x00; // No aspect ratio specified. stream.Write(buffer, 0, 13); // Write the global color table, which is the palette // for the first frame. We use local color tables only // if the palette changes for subsequent frames. palette = frame0.Palette; WriteGifPalette(stream, palette, bitCount, buffer); // Write out the frames. for(index = 0; index < image.NumFrames; ++index) { // Get the object for this frame. frame = image.GetFrame(index); // Write a graphics control extension for transparencies. if(frame.TransparentPixel != -1) { buffer[0] = (byte)0x21; buffer[1] = (byte)0xF9; buffer[2] = (byte)0x04; buffer[3] = (byte)0x01; buffer[4] = (byte)0x00; buffer[5] = (byte)0x00; buffer[6] = (byte)(frame.TransparentPixel); buffer[7] = (byte)0x00; stream.Write(buffer, 0, 8); } // Write the image descriptor header. buffer[0] = (byte)0x2C; Utils.WriteUInt16(buffer, 1, frame.OffsetX); Utils.WriteUInt16(buffer, 3, frame.OffsetY); Utils.WriteUInt16(buffer, 5, frame.Width); Utils.WriteUInt16(buffer, 7, frame.Height); if(frame.Palette != palette) { buffer[9] = (byte)((bitCount - 1) | 0x80); } else { buffer[9] = (byte)0x00; } stream.Write(buffer, 0, 10); // Write the local color table if necessary. if(frame.Palette != palette) { WriteGifPalette (stream, frame.Palette, bitCount, buffer); } // Compress and output the frame's contents. Compress(stream, buffer, bitCount, frame); } // Write the GIF file terminator. buffer[0] = (byte)0x3B; stream.Write(buffer, 0, 1); }
// Save a GIF image to the specified stream. This uses the "ungif" // approach of writing uncompressed code samples to avoid infringing // on the LZW patent. The patent may have expired already, but we // aren't taking any chances. Use PNG instead - it compresses better. public static void Save(Stream stream, Image image) { byte[] buffer = new byte [1024]; Frame frame0, frame; int bitCount, index; int[] palette; // Get the first frame in the image and the image's bit depth. frame0 = image.GetFrame(0); bitCount = Utils.FormatToBitCount(frame0.PixelFormat); // Write the GIF file header. buffer[0] = (byte)'G'; buffer[1] = (byte)'I'; buffer[2] = (byte)'F'; buffer[3] = (byte)'8'; buffer[4] = (byte)'9'; buffer[5] = (byte)'a'; Utils.WriteUInt16(buffer, 6, image.Width); Utils.WriteUInt16(buffer, 8, image.Height); buffer[10] = (byte)((bitCount - 1) | ((bitCount - 1) << 4) | 0x80); if (frame0.TransparentPixel != -1) { // Use the transparent pixel as the background color. buffer[11] = (byte)(frame0.TransparentPixel); } else { // Assume that index zero is the background color. buffer[11] = (byte)0x00; } buffer[12] = (byte)0x00; // No aspect ratio specified. stream.Write(buffer, 0, 13); // Write the global color table, which is the palette // for the first frame. We use local color tables only // if the palette changes for subsequent frames. palette = frame0.Palette; WriteGifPalette(stream, palette, bitCount, buffer); // Write out the frames. for (index = 0; index < image.NumFrames; ++index) { // Get the object for this frame. frame = image.GetFrame(index); // Write a graphics control extension for transparencies. if (frame.TransparentPixel != -1) { buffer[0] = (byte)0x21; buffer[1] = (byte)0xF9; buffer[2] = (byte)0x04; buffer[3] = (byte)0x01; buffer[4] = (byte)0x00; buffer[5] = (byte)0x00; buffer[6] = (byte)(frame.TransparentPixel); buffer[7] = (byte)0x00; stream.Write(buffer, 0, 8); } // Write the image descriptor header. buffer[0] = (byte)0x2C; Utils.WriteUInt16(buffer, 1, frame.OffsetX); Utils.WriteUInt16(buffer, 3, frame.OffsetY); Utils.WriteUInt16(buffer, 5, frame.Width); Utils.WriteUInt16(buffer, 7, frame.Height); if (frame.Palette != palette) { buffer[9] = (byte)((bitCount - 1) | 0x80); } else { buffer[9] = (byte)0x00; } stream.Write(buffer, 0, 10); // Write the local color table if necessary. if (frame.Palette != palette) { WriteGifPalette (stream, frame.Palette, bitCount, buffer); } // Compress and output the frame's contents. Compress(stream, buffer, bitCount, frame); } // Write the GIF file terminator. buffer[0] = (byte)0x3B; stream.Write(buffer, 0, 1); }
// Save a PNG image to the specified stream. public static void Save(Stream stream, Image image) { Frame frame = image.GetFrame(0); byte[] buffer = new byte [1024]; ChunkWriter writer = new ChunkWriter(stream); int colorType, bitDepth; int sigRed, sigGreen, sigBlue, sigAlpha; int paletteSize, posn; int[] palette; ZlibCompressor compressor; ScanlineWriter scanlineWriter; OutputFunc func; int y; // Determine the color type and bit depth for the image. sigRed = -1; sigGreen = -1; sigBlue = -1; sigAlpha = -1; paletteSize = 0; switch (frame.PixelFormat) { case PixelFormat.Format16bppRgb555: { sigRed = 5; sigGreen = 5; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format16bppRgb565: { sigRed = 5; sigGreen = 6; sigBlue = 5; colorType = 2; bitDepth = 8; } break; case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: { colorType = 2; bitDepth = 8; } break; case PixelFormat.Format1bppIndexed: { colorType = 3; bitDepth = 1; paletteSize = 2; } break; case PixelFormat.Format4bppIndexed: { colorType = 3; bitDepth = 4; paletteSize = 16; } break; case PixelFormat.Format8bppIndexed: { colorType = 3; bitDepth = 8; paletteSize = 256; } break; case PixelFormat.Format16bppArgb1555: { sigRed = 5; sigGreen = 5; sigBlue = 5; sigAlpha = 1; colorType = 6; bitDepth = 8; } break; case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppArgb: { colorType = 6; bitDepth = 8; } break; case PixelFormat.Format16bppGrayScale: { colorType = 0; bitDepth = 16; } break; case PixelFormat.Format48bppRgb: { colorType = 2; bitDepth = 16; } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { colorType = 6; bitDepth = 16; } break; default: throw new FormatException("unknown format"); } // Write out the PNG magic number. stream.Write(magic, 0, magic.Length); // Write the header chunk. Utils.WriteInt32B(buffer, 0, frame.Width); Utils.WriteInt32B(buffer, 4, frame.Height); buffer[8] = (byte)bitDepth; buffer[9] = (byte)colorType; buffer[10] = (byte)0; // Compression method. buffer[11] = (byte)0; // Filter method. buffer[12] = (byte)0; // Interlace method. writer.Write(PngReader.IHDR, buffer, 0, 13); // Write the significant bits chunk if necessary. if (sigAlpha != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; buffer[3] = (byte)sigAlpha; writer.Write(PngReader.sBIT, buffer, 0, 4); } else if (sigRed != -1) { buffer[0] = (byte)sigRed; buffer[1] = (byte)sigGreen; buffer[2] = (byte)sigBlue; writer.Write(PngReader.sBIT, buffer, 0, 3); } // Write the palette and transparency chunks. if (paletteSize > 0) { Array.Clear(buffer, 0, buffer.Length); palette = frame.Palette; if (palette != null) { for (posn = 0; posn < palette.Length && posn < paletteSize; ++posn) { buffer[posn * 3] = (byte)(palette[posn] >> 16); buffer[posn * 2 + 1] = (byte)(palette[posn] >> 8); buffer[posn * 2 + 2] = (byte)(palette[posn]); } } writer.Write(PngReader.PLTE, buffer, 0, paletteSize * 3); if (frame.TransparentPixel >= 0 && frame.TransparentPixel < paletteSize) { for (posn = 0; posn < paletteSize; ++posn) { buffer[posn] = (byte)0xFF; } buffer[frame.TransparentPixel] = (byte)0x00; writer.Write(PngReader.tRNS, buffer, 0, frame.TransparentPixel + 1); } } // Compress and write the scanlines to the output stream. compressor = new ZlibCompressor(writer); scanlineWriter = new ScanlineWriter (compressor, frame.Width, frame.PixelFormat); func = GetOutputFunc(frame.PixelFormat); for (y = 0; y < frame.Height; ++y) { func(frame, y, scanlineWriter.Buffer); scanlineWriter.FlushScanline(); } compressor.Finish(); // Write the end chunk. writer.Write(PngReader.IEND, buffer, 0, 0); }
/// <summary> /// <para>Constructs a new <see cref="T:Xsharp.Image"/> instance /// that represents an off-screen image that was loaded /// from a file.</para> /// </summary> /// /// <param name="screen"> /// <para>The screen upon which to create the new pixmap.</para> /// </param> /// /// <param name="filename"> /// <para>The file to load the image from.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>The <paramref name="filename"/> parameter is /// <see langword="null"/>.</para> /// </exception> /// /// <exception cref="T:System.FormatException"> /// <para>The image format is not recognized.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="filename"/> could not be /// loaded for some reason.</para> /// </exception> public Image(Screen screen, String filename) { Display dpy; if(filename == null) { throw new ArgumentNullException("filename"); } if(screen != null) { dpy = screen.DisplayOfScreen; } else { dpy = Application.Primary.Display; screen = dpy.DefaultScreenOfDisplay; } this.screen = screen; DotGNU.Images.Image img = new DotGNU.Images.Image(); img.Load(filename); Frame frame = img.GetFrame(0); try { dpy.Lock(); pixmapXImage = ConvertImage.FrameToXImage(screen, frame); maskXImage = ConvertImage.MaskToXImage(screen, frame); } finally { dpy.Unlock(); } }
// Set the dgImage field within this object. internal void SetDGImage(DotGNU.Images.Image dgImage) { flags = 0; #if !ECMA_COMPAT switch(dgImage.LoadFormat) { case DotGNU.Images.Image.Png: rawFormat = ImageFormat.Png; break; case DotGNU.Images.Image.Jpeg: rawFormat = ImageFormat.Jpeg; break; case DotGNU.Images.Image.Gif: rawFormat = ImageFormat.Gif; break; case DotGNU.Images.Image.Tiff: rawFormat = ImageFormat.Tiff; break; case DotGNU.Images.Image.Bmp: rawFormat = ImageFormat.Bmp; break; case DotGNU.Images.Image.Icon: rawFormat = ImageFormat.Icon; break; case DotGNU.Images.Image.Exif: rawFormat = ImageFormat.Exif; break; } frameDimensionsList = new Guid [0]; this.dgImage = dgImage; // If we are loading an icon, set the size of the image // to the size of the first icon if (rawFormat == ImageFormat.Icon) { width = dgImage.GetFrame(0).Width; height = dgImage.GetFrame(0).Height; } else { width = dgImage.Width; height = dgImage.Height; } #else this.dgImage = dgImage; width = dgImage.GetFrame(0).Width; height = dgImage.GetFrame(0).Height; #endif horizontalResolution = Graphics.DefaultScreenDpi; verticalResolution = Graphics.DefaultScreenDpi; pixelFormat = (System.Drawing.Imaging.PixelFormat) (dgImage.PixelFormat); }
// 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, Image 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); } }
// Save a JPEG image to the specified stream. public static void Save(Stream stream, Image image) { // Determine if we actually have the JPEG library. if(!JpegLib.JpegLibraryPresent()) { throw new FormatException("libjpeg is not available"); } // Create the compression object. JpegLib.jpeg_compress_struct cinfo; cinfo = new JpegLib.jpeg_compress_struct(); cinfo.err = JpegLib.CreateErrorHandler(); JpegLib.jpeg_create_compress(ref cinfo); // Initialize the destination manager. JpegLib.StreamToDestinationManager(ref cinfo, stream); // Get the frame to be written. Frame frame = image.GetFrame(0); // Set the JPEG compression parameters. cinfo.image_width = (UInt)(frame.Width); cinfo.image_height = (UInt)(frame.Height); cinfo.input_components = (Int)3; cinfo.in_color_space = JpegLib.J_COLOR_SPACE.JCS_RGB; JpegLib.jpeg_set_defaults(ref cinfo); // Start the compression process. JpegLib.jpeg_start_compress(ref cinfo, (Int)1); // Write the scanlines to the image. int posn, width, offset, stride; width = frame.Width; stride = frame.Stride; byte[] data = frame.Data; PixelFormat format = frame.PixelFormat; IntPtr buf = Marshal.AllocHGlobal(width * 3); byte *pbuf = (byte *)buf; while(((int)(cinfo.next_scanline)) < ((int)(cinfo.image_height))) { // Convert the source scanline into the JCS_RGB format. offset = ((int)(cinfo.next_scanline)) * stride; switch(format) { case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppArgb1555: { Rgb555(data, offset, width, pbuf); } break; case PixelFormat.Format16bppRgb565: { Rgb565(data, offset, width, pbuf); } break; case PixelFormat.Format24bppRgb: { Rgb24bpp(data, offset, width, pbuf); } break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: { Rgb32bpp(data, offset, width, pbuf); } break; case PixelFormat.Format1bppIndexed: { Rgb1bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format4bppIndexed: { Rgb4bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format8bppIndexed: { Rgb8bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format16bppGrayScale: { GrayScale16bpp(data, offset, width, pbuf); } break; case PixelFormat.Format48bppRgb: { Rgb48bpp(data, offset, width, pbuf); } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { Rgb64bpp(data, offset, width, pbuf); } break; } // Write the scanline to the buffer. JpegLib.jpeg_write_scanlines (ref cinfo, ref buf, (UInt)1); } Marshal.FreeHGlobal(buf); // Finish the compression process. JpegLib.jpeg_finish_compress(ref cinfo); // Clean everything up. JpegLib.FreeDestinationManager(ref cinfo); JpegLib.jpeg_destroy_compress(ref cinfo); JpegLib.FreeErrorHandler(cinfo.err); }
// 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, Image 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); } }
// Determine if an image only has indexed frames in it and // that all frames have the same pixel format. public static bool IsGifEncodable(Image image) { int index; Frame frame; PixelFormat format = (PixelFormat)(-1); if(image.NumFrames == 0) { return false; } for(index = 0; index < image.NumFrames; ++index) { frame = image.GetFrame(index); if((frame.PixelFormat & PixelFormat.Indexed) == 0) { return false; } if(format != (PixelFormat)(-1) && format != frame.PixelFormat) { return false; } format = frame.PixelFormat; } return true; }