예제 #1
0
        /// <summary>
        /// Raised when a new index is selected from ImageSelector.
        /// Loads the GIF file of that filename.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event data.</param>
        private void ImageSelector_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!SavePrompt())
                return;

            loaded = false;
            changed = false;
            filePath = Path.Combine(filesPath, (string)ImageSelector.Items[ImageSelector.SelectedIndex]);

            if (gifImage != null)
                foreach (GifFrame<Bitmap> frame in gifImage.Frames)
                    frame.Image.Dispose();

            if (desiredFrames != null)
                foreach (Bitmap frame in desiredFrames)
                    frame.Dispose();

            gifImage = null;
            frameIndex = -1;
            desiredFrames = null;
            ImageComparison.Panel1.BackgroundImage = null;
            ImageComparison.Panel2.BackgroundImage = null;
            ImageSourceColor.BackColor = Color.Transparent;
            ImageDesiredColor.BackColor = Color.Transparent;
            ImageSourcePalette.BackColor = PaletteControls.BackColor;
            ImageDesiredPalette.BackColor = PaletteControls.BackColor;
            ImageSourcePalette.Controls.Clear();
            ImageDesiredPalette.Controls.Clear();
            foreach (Panel panel in sourceSwatches)
                panel.Dispose();
            foreach (Panel panel in desiredSwatches)
                panel.Dispose();
            sourceSwatches.Clear();
            desiredSwatches.Clear();
            SourceAlphaCode.ResetText();
            SourceColorCode.ResetText();
            DesiredAlphaCode.ResetText();
            DesiredColorCode.ResetText();
            FrameControls.Enabled = false;
            PaletteControls.Enabled = false;
            ColorControls.Enabled = false;
            ErrorLabel.Visible = false;
            currentColor = Color.Empty;

            FileStream gifStream = null;
            try
            {
                gifStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                gifImage = GifImage.OfBitmap(gifStream);
            }
            catch (Exception)
            {
                Console.WriteLine("An error occurred attempting to load the file: " + filePath);
                ShowError("An error occurred attempting to load this file.");
                return;
            }
            finally
            {
                if (gifStream != null)
                    gifStream.Dispose();
            }
            Indexer.UseTimingsFrom(gifImage);

            AlphaRemappingTable map = new AlphaRemappingTable();
            string mapFile = Path.ChangeExtension(filePath, AlphaRemappingTable.FileExtension);
            if (File.Exists(mapFile))
                map.LoadMap(mapFile);

            colorMappingTable.Clear();

            foreach (var frame in gifImage.Frames)
                BuildColorMap(frame.GetColorTable(), map);

            sourceSwatches.Capacity = colorMappingTable.Count;
            desiredSwatches.Capacity = colorMappingTable.Count;

            int swatchSize = ImageSourcePalette.Height - 2;
            Size size = new Size(swatchSize, swatchSize);
            Point location = new Point(1, 1);

            ImageSourcePalette.SuspendLayout();
            ImageDesiredPalette.SuspendLayout();

            int mappingIndex = 0;
            foreach (var colorMapping in colorMappingTable)
            {
                Panel sourcePanel = new Panel() { Size = size, Location = location };
                Panel desiredPanel = new Panel() { Size = size, Location = location };
                sourcePanel.Tag = desiredPanel;
                desiredPanel.Tag = sourcePanel;
                sourceSwatches.Add(sourcePanel);
                desiredSwatches.Add(desiredPanel);
                ImageSourcePalette.Controls.Add(sourcePanel);
                ImageDesiredPalette.Controls.Add(desiredPanel);
                sourceSwatches[mappingIndex].Click += Swatch_Clicked;
                desiredSwatches[mappingIndex].Click += Swatch_Clicked;
                sourceSwatches[mappingIndex].BackColor = colorMapping.Key;
                desiredSwatches[mappingIndex].BackColor = colorMapping.Value;
                if (mappingIndex == 0)
                    currentColor = colorMapping.Key;
                mappingIndex++;
                location.X += swatchSize + 1;
            }
            location.Y = 0;
            Panel blankSourcePanel =
                new Panel() { Size = ImageSourcePalette.Size, Location = location, BackColor = SystemColors.Control };
            ImageSourcePalette.Controls.Add(blankSourcePanel);
            Panel blankDesiredPanel =
                new Panel() { Size = ImageDesiredPalette.Size, Location = location, BackColor = SystemColors.Control };
            ImageDesiredPalette.Controls.Add(blankDesiredPanel);
            ImageSourcePalette.ResumeLayout();
            ImageDesiredPalette.ResumeLayout();
            ImageSourcePalette.BackColor = ImageComparison.BackColor;
            ImageDesiredPalette.BackColor = ImageComparison.BackColor;

            desiredFrames = new Bitmap[gifImage.Frames.Length];
            for (int i = 0; i < desiredFrames.Length; i++)
                desiredFrames[i] = (Bitmap)gifImage.Frames[i].Image.Clone();
            UpdateDesiredFrames();

            FrameControls.Enabled = true;
            PaletteControls.Enabled = true;
            ColorControls.Enabled = true;
            SaveCommand.Enabled = true;

            UpdateSelectedFrame(0);
            UpdateColorHex();
            UpdateColorDisplay();

            loaded = true;
        }
 /// <summary>
 /// Creates a new <see cref="T:DesktopSprites.SpriteManagement.BitmapFrame"/> from the raw buffer, loading extra transparency
 /// information and adjusting the colors as required by the transparency.
 /// </summary>
 /// <param name="buffer">The raw buffer.</param>
 /// <param name="palette">The color palette.</param>
 /// <param name="transparentIndex">The index of the transparent color.</param>
 /// <param name="stride">The stride width of the buffer.</param>
 /// <param name="width">The logical width of the buffer.</param>
 /// <param name="height">The logical height of the buffer.</param>
 /// <param name="depth">The bit depth of the buffer.</param>
 /// <param name="hashCode">The hash code of the frame.</param>
 /// <param name="fileName">The path to the GIF file being loaded.</param>
 /// <returns>A new <see cref="T:DesktopSprites.SpriteManagement.BitmapFrame"/> for the frame held in the raw buffer.</returns>
 private BitmapFrame BitmapFrameFromBuffer(byte[] buffer, RgbColor[] palette, int transparentIndex,
     int stride, int width, int height, int depth, int hashCode, string fileName)
 {
     return Disposable.SetupSafely(
         BitmapFrame.FromBuffer(buffer, palette, transparentIndex, stride, width, height, depth, hashCode),
         frame =>
         {
             if (IsAlphaBlended)
             {
                 // Check for an alpha remapping table, and apply it if one exists.
                 string mapFilePath = Path.ChangeExtension(fileName, AlphaRemappingTable.FileExtension);
                 if (File.Exists(mapFilePath))
                 {
                     AlphaRemappingTable map = new AlphaRemappingTable();
                     map.LoadMap(mapFilePath);
                     ColorPalette colorPalette = frame.Image.Palette;
                     for (int i = 0; i < colorPalette.Entries.Length; i++)
                     {
                         Color color = colorPalette.Entries[i];
                         ArgbColor argbColor;
                         if (map.TryGetMapping(new RgbColor(color.R, color.G, color.B), out argbColor))
                             colorPalette.Entries[i] = Color.FromArgb(argbColor.ToArgb());
                     }
                     frame.Image.Palette = colorPalette;
                     // We only need to pre-multiply when we add an alpha channel ourselves, as GIFs only support 1 bit transparency.
                     frame.Image.PreMultiplyAlpha();
                 }
             }
             else
             {
                 frame.Image.RemapColors(paletteMapping);
             }
         });
 }