コード例 #1
0
ファイル: GifWriter.cs プロジェクト: i-e-b/Form8sn
        // Determine if an image only has indexed frames in it and
        // that all frames have the same pixel format.
        public static bool IsGifEncodable(PortableImage 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);
        }
コード例 #2
0
        // Save a BMP image to the specified stream.
        public static void Save(Stream stream, PortableImage 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);
        }
コード例 #3
0
ファイル: GifWriter.cs プロジェクト: i-e-b/Form8sn
        // 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, PortableImage 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);
        }
コード例 #4
0
ファイル: PngWriter.cs プロジェクト: i-e-b/Form8sn
        // Save a PNG image to the specified stream.
        public static void Save(Stream stream, PortableImage 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);
        }
コード例 #5
0
        // 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);
            }
        }