Ejemplo n.º 1
0
        /// <summary>
        /// Converts a given bitmap, modified by given settings, in binary data.
        /// </summary>
        /// <param name="bmp">The bitmap, which will be converted.</param>
        /// <param name="palette">The list containing all colors of the palette to use.</param>
        /// <param name="settings">The settings determining the final binary data output.</param>
        /// <returns><see cref="Tuple"/> containing 2 byte arrays.</returns>
        public static (byte[] indexData, byte[] paletteData) Save(Bitmap bmp, IndexedImageSettings settings)
        {
            // Create swizzle point list
            var points = GetPointSequence(settings.Swizzle, settings.Width, settings.Height, settings.PadWidth, settings.PadHeight);

            // Get swizzled collection of colors
            var colors = new List <Color>();
            var data   = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                var imagePtr = (int *)data.Scan0;
                if (imagePtr == null)
                {
                    throw new ArgumentNullException(nameof(imagePtr));
                }

                foreach (var point in points)
                {
                    var x = Clamp(point.X, 0, bmp.Width);
                    var y = Clamp(point.Y, 0, bmp.Height);

                    colors.Add(Color.FromArgb(imagePtr[y * bmp.Width + x]));
                }
            }
            bmp.UnlockBits(data);

            // Decompose/Quantize colors
            var(indices, palette) = settings.QuantizationSettings != null?
                                    settings.IndexEncoding.Quantize(colors, settings.QuantizationSettings) :
                                        settings.IndexEncoding.Decompose(colors);

            return(settings.IndexEncoding.Save(indices), settings.Encoding.Save(palette));
        }
Ejemplo n.º 2
0
        protected override (Bitmap Image, IList <Color> Palette) Transcode(BitmapInfo bitmapInfo, EncodingInfo imageEncoding, EncodingInfo paletteEncoding, IProgress <ProgressReport> progress)
        {
            var img           = bitmapInfo.Image;
            var indexEncoding = BTX.IndexEncodings[imageEncoding.EncodingIndex];
            var palEncoding   = BTX.PaletteEncodings[paletteEncoding.EncodingIndex];
            var settings      = new IndexedImageSettings(indexEncoding, palEncoding, img.Width, img.Height)
            {
                QuantizationSettings = new QuantizationSettings(new WuColorQuantizer(6, 3), img.Width, img.Height)
                {
                    ParallelCount = 8
                }
            };
            var data = Kanvas.Kolors.Save(img, settings);

            (_format.Texture, _format.Palette) = Kanvas.Kolors.Load(data.indexData, data.paletteData, settings);
            return(_format.Texture, _format.Palette);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="input"></param>
        public BTX(Stream input)
        {
            using (var br = new BinaryReaderX(input, true))
            {
                // Header
                Header = br.ReadType <FileHeader>();
                br.SeekAlignment();
                FileName = br.ReadCStringASCII();

                // Setup
                var dataLength        = Header.Width * Header.Height;
                var paletteDataLength = Header.ColorCount * 4;

                // Image
                br.BaseStream.Position = Header.ImageOffset;
                var texture = br.ReadBytes(dataLength);

                // Palette
                if (Header.Format == ImageFormat.Palette_8)
                {
                    br.BaseStream.Position = Header.PaletteOffset;
                    var palette = br.ReadBytes(paletteDataLength);

                    var settings = new IndexedImageSettings(IndexEncodings[(int)Header.Format], PaletteEncodings[(int)Header.Format], Header.Width, Header.Height);
                    var data     = Kolors.Load(texture, palette, settings);
                    Texture           = data.image;
                    Palette           = data.palette;
                    FormatName        = IndexEncodings[(int)Header.Format].FormatName;
                    PaletteFormatName = PaletteEncodings[(int)Header.Format].FormatName;
                    HasPalette        = true;
                }
                else
                {
                    var settings = new ImageSettings(Encodings[(int)Header.Format], Header.Width, Header.Height);
                    Texture    = Kolors.Load(texture, settings);
                    FormatName = Encodings[(int)Header.Format].FormatName;
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="output"></param>
        public void Save(Stream output)
        {
            using (var bw = new BinaryWriterX(output, true))
            {
                // Updates
                Header.Width  = (short)Texture.Width;
                Header.Height = (short)Texture.Height;

                // Header
                bw.WriteType(Header);
                bw.WriteAlignment();
                bw.WriteString(FileName, Encoding.ASCII, false);
                bw.WriteAlignment();

                // Setup
                if (Header.Format == ImageFormat.Palette_8)
                {
                    var settings = new IndexedImageSettings(IndexEncodings[(int)Header.Format], PaletteEncodings[(int)Header.Format], Header.Width, Header.Height)
                    {
                        QuantizationSettings = new QuantizationSettings(new WuColorQuantizer(6, 3), Header.Width, Header.Height)
                        {
                            ColorCount    = 256,
                            ParallelCount = 8
                        }
                    };
                    var data = Kolors.Save(Texture, settings);

                    bw.Write(data.indexData);
                    bw.Write(data.paletteData);
                }
                else
                {
                    var settings = new ImageSettings(Encodings[(int)Header.Format], Header.Width, Header.Height);
                    var data     = Kolors.Save(Texture, settings);

                    bw.Write(data);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Loads the binary data with given settings as an image.
        /// </summary>
        /// <param name="bytes">Byte array containing the binary image data.</param>
        /// <param name="paletteBytes">Byte array containing the binary palette data.</param>
        /// <param name="settings">The settings determining the final image output.</param>
        /// <returns>Loaded bitmap, indices and colors.</returns>
        public static (Bitmap image, IList <Color> palette) Load(byte[] bytes, byte[] paletteBytes, IndexedImageSettings settings)
        {
            int width = settings.Width, height = settings.Height;

            var points  = GetPointSequence(settings.Swizzle, settings.Width, settings.Height, settings.PadWidth, settings.PadHeight);
            var indices = settings.IndexEncoding.Load(bytes);
            var palette = settings.Encoding.Load(paletteBytes).ToList();

            var bmp  = new Bitmap(width, height);
            var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                var imagePtr = (int *)data.Scan0;
                if (imagePtr == null)
                {
                    throw new ArgumentNullException(nameof(imagePtr));
                }

                var colors = settings.IndexEncoding.Compose(indices, palette);
                foreach (var(point, color) in points.Zip(colors, Tuple.Create))
                {
                    int x = point.X, y = point.Y;
                    if (0 > x || x >= width || 0 > y || y >= height)
                    {
                        continue;
                    }

                    imagePtr[data.Stride * y / 4 + x] = color.ToArgb();
                }
            }
            bmp.UnlockBits(data);

            return(bmp, palette);
        }