Exemplo n.º 1
0
        /// <summary>
        /// Writes a 1 bit image with a color palette. The color palette has 2 entry's with 4 bytes for each entry.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="stream">The <see cref="Stream"/> to write to.</param>
        /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
        private void Write1BitColor <TPixel>(Stream stream, ImageFrame <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            using IQuantizer <TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration, new QuantizerOptions()
            {
                MaxColors = 2
            });
            using IndexedImageFrame <TPixel> quantized   = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());
            using IMemoryOwner <byte> colorPaletteBuffer = this.memoryAllocator.Allocate <byte>(ColorPaletteSize1Bit, AllocationOptions.Clean);

            Span <byte>           colorPalette          = colorPaletteBuffer.GetSpan();
            ReadOnlySpan <TPixel> quantizedColorPalette = quantized.Palette.Span;

            this.WriteColorPalette(stream, quantizedColorPalette, colorPalette);

            ReadOnlySpan <byte> quantizedPixelRow = quantized.DangerousGetRowSpan(0);
            int rowPadding = quantizedPixelRow.Length % 8 != 0 ? this.padding - 1 : this.padding;

            for (int y = image.Height - 1; y >= 0; y--)
            {
                quantizedPixelRow = quantized.DangerousGetRowSpan(y);

                int endIdx = quantizedPixelRow.Length % 8 == 0 ? quantizedPixelRow.Length : quantizedPixelRow.Length - 8;
                for (int i = 0; i < endIdx; i += 8)
                {
                    Write1BitPalette(stream, i, i + 8, quantizedPixelRow);
                }

                if (quantizedPixelRow.Length % 8 != 0)
                {
                    int startIdx = quantizedPixelRow.Length - 7;
                    endIdx = quantizedPixelRow.Length;
                    Write1BitPalette(stream, startIdx, endIdx, quantizedPixelRow);
                }

                for (int i = 0; i < rowPadding; i++)
                {
                    stream.WriteByte(0);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Writes an 4 bit color image with a color palette. The color palette has 16 entry's with 4 bytes for each entry.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="stream">The <see cref="Stream"/> to write to.</param>
        /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
        private void Write4BitColor <TPixel>(Stream stream, ImageFrame <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            using IQuantizer <TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration, new QuantizerOptions()
            {
                MaxColors = 16
            });
            using IndexedImageFrame <TPixel> quantized   = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());
            using IMemoryOwner <byte> colorPaletteBuffer = this.memoryAllocator.Allocate <byte>(ColorPaletteSize4Bit, AllocationOptions.Clean);

            Span <byte>           colorPalette          = colorPaletteBuffer.GetSpan();
            ReadOnlySpan <TPixel> quantizedColorPalette = quantized.Palette.Span;

            this.WriteColorPalette(stream, quantizedColorPalette, colorPalette);

            ReadOnlySpan <byte> pixelRowSpan = quantized.DangerousGetRowSpan(0);
            int rowPadding = pixelRowSpan.Length % 2 != 0 ? this.padding - 1 : this.padding;

            for (int y = image.Height - 1; y >= 0; y--)
            {
                pixelRowSpan = quantized.DangerousGetRowSpan(y);

                int endIdx = pixelRowSpan.Length % 2 == 0 ? pixelRowSpan.Length : pixelRowSpan.Length - 1;
                for (int i = 0; i < endIdx; i += 2)
                {
                    stream.WriteByte((byte)((pixelRowSpan[i] << 4) | pixelRowSpan[i + 1]));
                }

                if (pixelRowSpan.Length % 2 != 0)
                {
                    stream.WriteByte((byte)((pixelRowSpan[pixelRowSpan.Length - 1] << 4) | 0));
                }

                for (int i = 0; i < rowPadding; i++)
                {
                    stream.WriteByte(0);
                }
            }
        }
Exemplo n.º 3
0
        public void SinglePixelOpaque()
        {
            Configuration config    = Configuration.Default;
            var           quantizer = new WuQuantizer(new QuantizerOptions {
                Dither = null
            });

            using var image = new Image <Rgba32>(config, 1, 1, Color.Black);
            ImageFrame <Rgba32> frame = image.Frames.RootFrame;

            using IQuantizer <Rgba32> frameQuantizer = quantizer.CreatePixelSpecificQuantizer <Rgba32>(config);
            using IndexedImageFrame <Rgba32> result  = frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds());

            Assert.Equal(1, result.Palette.Length);
            Assert.Equal(1, result.Width);
            Assert.Equal(1, result.Height);

            Assert.Equal(Color.Black, (Color)result.Palette.Span[0]);
            Assert.Equal(0, result.DangerousGetRowSpan(0)[0]);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Writes an 8 bit color image with a color palette. The color palette has 256 entry's with 4 bytes for each entry.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="stream">The <see cref="Stream"/> to write to.</param>
        /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
        /// <param name="colorPalette">A byte span of size 1024 for the color palette.</param>
        private void Write8BitColor <TPixel>(Stream stream, ImageFrame <TPixel> image, Span <byte> colorPalette)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            using IQuantizer <TPixel> frameQuantizer   = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration);
            using IndexedImageFrame <TPixel> quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());

            ReadOnlySpan <TPixel> quantizedColorPalette = quantized.Palette.Span;

            this.WriteColorPalette(stream, quantizedColorPalette, colorPalette);

            for (int y = image.Height - 1; y >= 0; y--)
            {
                ReadOnlySpan <byte> pixelSpan = quantized.DangerousGetRowSpan(y);
                stream.Write(pixelSpan);

                for (int i = 0; i < this.padding; i++)
                {
                    stream.WriteByte(0);
                }
            }
        }