TRANSPARENT GIF IMAGE MAKER
Creating Transparent GIF Images
Now includes a VB version of the listing.
This process is easy enough when you know how but is nevertheless a little more complex than it should be.
To save a GIF with a transparency key you need to modify the colour palette of the image. There are a few problems associated with this. If you're creating an image, you'll be using a true colour format such as 24 or 32 bit per pixel non indexed. This is because you cannot obtain a Graphics object using Graphics.FromImage for any images with an indexed pixel format. Saving such an image as a GIF file will create a standard spread palette for you with the range of colours seen in figure 1.
Figure 1: The standard spread palette provided by GDI+
Unfortunately, at no point during the save process are you given the opportunity to choose a transparent colour so you need to take the saved image and re-save it with a modified palette.
This in itself presents a problem because once a GIF image has been created, even though you can get hold of and manipulate the palette using the Bitmap.Palette property, GDI+ refuses to save the image with anything other than its original palette.
To work around these limitations it's necessary to create a new, blank 8 bit per pixel, indexed palette image, modify it's bitmap to be the same as the original images, copy all the pixel data from the original to the new and then save the new image.
As a demonstration of this process, and to provide a useful tool, the code in listing 1 is an application that enables you to load a GIF image, choose a transparent colour and save the GIF. panel1_Click is the method with the actual GIF manipulation.
Listing 1: TransparentGifCreator.cs
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
 
namespace TransparentGifCreator
{
 /// <summary>
 /// Summary description for Form1.
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {
   private System.Windows.Forms.PictureBox pictureBox1;
   private System.Windows.Forms.Panel panel1;
   private System.Windows.Forms.Button button1;
   private System.Windows.Forms.Button button2;
   private System.Windows.Forms.Button button3;
   private System.ComponentModel.IContainer components;
 
   Image _gifImage;
   private System.Windows.Forms.Timer timer1;
   ColorPalette cp;
   int CurrentEntry;
 
   public Form1()
   {
     //
     // Required for Windows Form Designer support
     //
     InitializeComponent();
 
     //
     // TODO: Add any constructor code after InitializeComponent call
     //
   }
 
   /// <summary>
   /// Clean up any resources being used.
   /// </summary>
   protected override void Dispose( bool disposing )
   {
     if( disposing )
     {
       if (components != null)
       {
         components.Dispose();
       }
     }
     base.Dispose( disposing );
   }
 
    #region Windows Form Designer generated code
   /// <summary>
   /// Required method for Designer support - do not modify
   /// the contents of this method with the code editor.
   /// </summary>
   private void InitializeComponent()
   {
     this.components = new System.ComponentModel.Container();
     this.pictureBox1 = new System.Windows.Forms.PictureBox();
     this.panel1 = new System.Windows.Forms.Panel();
     this.button1 = new System.Windows.Forms.Button();
     this.button2 = new System.Windows.Forms.Button();
     this.button3 = new System.Windows.Forms.Button();
     this.timer1 = new System.Windows.Forms.Timer(this.components);
     this.SuspendLayout();
     //
     // pictureBox1
     //
     this.pictureBox1.Location = new System.Drawing.Point(96, ;
     this.pictureBox1.Name = "pictureBox1";
     this.pictureBox1.Size = new System.Drawing.Size(144, 144);
     this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
     this.pictureBox1.TabIndex = 0;
     this.pictureBox1.TabStop = false;
     //
     // panel1
     //
     this.panel1.Location = new System.Drawing.Point(8, 168);
     this.panel1.Name = "panel1";
     this.panel1.Size = new System.Drawing.Size(144, 144);
     this.panel1.TabIndex = 1;
     this.panel1.Click += new System.EventHandler(this.panel1_Click);
     this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
     this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
     //
     // button1
     //
     this.button1.Location = new System.Drawing.Point(200, 176);
     this.button1.Name = "button1";
     this.button1.Size = new System.Drawing.Size(88, 24);
     this.button1.TabIndex = 2;
     this.button1.Text = "Open";
     this.button1.Click += new System.EventHandler(this.button1_Click);
     //
     // button2
     //
     this.button2.Location = new System.Drawing.Point(200, 216);
     this.button2.Name = "button2";
     this.button2.Size = new System.Drawing.Size(88, 24);
     this.button2.TabIndex = 2;
     this.button2.Text = "Save";
     this.button2.Click += new System.EventHandler(this.button2_Click);
     //
     // button3
     //
     this.button3.Location = new System.Drawing.Point(200, 256);
     this.button3.Name = "button3";
     this.button3.Size = new System.Drawing.Size(88, 24);
     this.button3.TabIndex = 2;
     this.button3.Text = "Exit";
     this.button3.Click += new System.EventHandler(this.button3_Click);
     //
     // timer1
     //
     this.timer1.Enabled = true;
     this.timer1.Interval = 250;
     this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
     //
     // Form1
     //
     this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
     this.ClientSize = new System.Drawing.Size(328, 325);
     this.Controls.Add(this.button1);
     this.Controls.Add(this.panel1);
     this.Controls.Add(this.pictureBox1);
     this.Controls.Add(this.button2);
     this.Controls.Add(this.button3);
     this.Name = "Form1";
     this.Text = "Form1";
     this.ResumeLayout(false);
 
   }
    #endregion
 
   /// <summary>
   /// The main entry point for the application.
   /// </summary>
   [STAThread]
   static void Main()
   {
     Application.Run(new Form1());
   }
 
   private void panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
   {
     if(cp==null)
       return;
 
     for(float y=0;y<16;y++)
       for(float x=0;x<16;x++)
       {
         Color c=Color.Black;
         if( ((16*y) + x)<cp.Entries.Length)
           c=cp.Entries[(int)((16*y)+x)];
         SolidBrush sb=new SolidBrush(Color.FromArgb(255,c));
         float w=((float)this.panel1.Width)/16;
         float h=((float)this.panel1.Height)/16;
         e.Graphics.FillRectangle(sb,w*x,h*y,w,h);
         if(c.A!=255)
         {
           if(showTrans)
             e.Graphics.DrawRectangle(Pens.Black,w*x,h*y,w-1,h-1);
           else
             e.Graphics.DrawRectangle(Pens.White,w*x,h*y,w-1,h-1);
         }
 
         sb.Dispose();
       }
   }
 
 
   private void panel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
   {
     int y=(int)(((float)e.Y)/(((float)this.panel1.Width)/16f));
     int x=(int)(((float)e.X)/(((float)this.panel1.Height)/16f));
     CurrentEntry=(int)((16*y)+x);
     if(cp!=null)
     {
       if(CurrentEntry>=cp.Entries.Length)
         CurrentEntry=cp.Entries.Length-1;
       //Little bit of diagnostic for the palette chooser below
       //System.Diagnostics.Trace.WriteLine(string.Format("{0},{1}, adjusted={4},{5} entry={2} Colour={3}",e.X,e.Y,CurrentEntry,cp.Entries[CurrentEntry].ToString(),x,y));
     }
   }
 
   private void panel1_Click(object sender, System.EventArgs e)
   {
     //Creates a new GIF image with a modified colour palette
     if(cp!=null)
     {
       //Create a new 8 bit per pixel image
       Bitmap bm=new Bitmap(_gifImage.Width,_gifImage.Height,PixelFormat.Format8bppIndexed);
       //get it's palette
       ColorPalette ncp=bm.Palette;
 
       //copy all the entries from the old palette removing any transparency
       int n=0;
       foreach(Color c in cp.Entries)
         ncp.Entries[n++]=Color.FromArgb(255,c);
 
       //Set the newly selected transparency
       ncp.Entries[CurrentEntry]=Color.FromArgb(0,cp.Entries[CurrentEntry]);
       //re-insert the palette
       bm.Palette=ncp;
 
       //now to copy the actual bitmap data
       //lock the source and destination bits
       BitmapData src=((Bitmap)_gifImage).LockBits(new Rectangle(0,0,_gifImage.Width,_gifImage.Height),ImageLockMode.ReadOnly,_gifImage.PixelFormat);
       BitmapData dst=bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height),ImageLockMode.WriteOnly,bm.PixelFormat);
 
       //uses pointers so we need unsafe code.
       //the project is also compiled with /unsafe
       unsafe
       {
         //steps through each pixel
         for(int y=0;y<_gifImage.Height;y++)
           for(int x=0;x<_gifImage.Width;x++)
           {
             //transferring the bytes
             ((byte *)dst.Scan0.ToPointer())[(dst.Stride*y)+x]=((byte *)src.Scan0.ToPointer())[(src.Stride*y)+x];
           }
       }
 
       //all done, unlock the bitmaps
       ((Bitmap)_gifImage).UnlockBits(src);
       bm.UnlockBits(dst);
 
       //clear out the picturebox
       this.pictureBox1.Image=null;
       _gifImage.Dispose();
       //set the new image in place
       _gifImage=bm;
       cp=_gifImage.Palette;
       this.pictureBox1.Image=_gifImage;
     }
   }
 
   private void button1_Click(object sender, System.EventArgs e)
   {
     OpenFileDialog dlg=new OpenFileDialog();
     dlg.Filter="GIF files|*.GIF";
     if(dlg.ShowDialog()==DialogResult.OK)
     {
       _gifImage=Image.FromFile(dlg.FileName);
       this.pictureBox1.Image=_gifImage;
       cp=_gifImage.Palette;
       this.panel1.Invalidate();
     }
   }
 
   private void button2_Click(object sender, System.EventArgs e)
   {
     SaveFileDialog dlg=new SaveFileDialog();
     dlg.Filter="GIF files|*.gif";
     dlg.DefaultExt=".gif";
     dlg.AddExtension=true;
     if(dlg.ShowDialog()==DialogResult.OK)
     {
       _gifImage.Save(dlg.FileName,ImageFormat.Gif);
     }
   }
 
   private void button3_Click(object sender, System.EventArgs e)
   {
     Application.Exit();
   }
 
   bool showTrans;
 
   private void timer1_Tick(object sender, System.EventArgs e)
   {
     showTrans^=true;
     Graphics g=this.panel1.CreateGraphics();
     //I do this rather than invalidate the panel because
     //the panel draws its background ans so flickers horribly.
     PaintEventArgs pe=new PaintEventArgs(g,new Rectangle(0,0,this.panel1.Width,this.panel1.Height));
     this.panel1_Paint(this,pe);
     g.Dispose();
   }
 }
}
 
To perform the same task in VB the Marshal class can be used to access the image byte array as shown in the following listing.
 
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports System.Runtime.InteropServices
 
Listing 2. TransparentGifCreator.VB 
 
Namespace TransparentGifCreator
  '/ <summary>
  '/ Summary description for Form1.
  '/ </summary>
 
  Public Class Form1
    Inherits System.Windows.Forms.Form
    Private pictureBox1 As System.Windows.Forms.PictureBox
    Private WithEvents panel1 As System.Windows.Forms.Panel
    Private WithEvents button1 As System.Windows.Forms.Button
    Private WithEvents button2 As System.Windows.Forms.Button
    Private WithEvents button3 As System.Windows.Forms.Button
    Private components As System.ComponentModel.IContainer
 
    Private _gifImage As Image
    Private WithEvents timer1 As System.Windows.Forms.Timer
    Private cp As ColorPalette
    Private CurrentEntry As Integer
 
 
    Public Sub New()
      '
      ' Required for Windows Form Designer support
      '
      InitializeComponent()
    End Sub 'New
 
    '
    ' TODO: Add any constructor code after InitializeComponent call
    '
 
    '/ <summary>
    '/ Clean up any resources being used.
    '/ </summary>
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      If disposing Then
        If Not (components Is Nothing) Then
          components.Dispose()
        End If
      End If
      MyBase.Dispose(disposing)
    End Sub 'Dispose
 
#Region "Windows Form Designer generated code"
 
    '/ <summary>
    '/ Required method for Designer support - do not modify
    '/ the contents of this method with the code editor.
    '/ </summary>
    Private Sub InitializeComponent()
      Me.components = New System.ComponentModel.Container
      Me.pictureBox1 = New System.Windows.Forms.PictureBox
      Me.panel1 = New System.Windows.Forms.Panel
      Me.button1 = New System.Windows.Forms.Button
      Me.button2 = New System.Windows.Forms.Button
      Me.button3 = New System.Windows.Forms.Button
      Me.timer1 = New System.Windows.Forms.Timer(Me.components)
      Me.SuspendLayout()
      '
      ' pictureBox1
      '
      Me.pictureBox1.Location = New System.Drawing.Point(96,
      Me.pictureBox1.Name = "pictureBox1"
      Me.pictureBox1.Size = New System.Drawing.Size(144, 144)
      Me.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
      Me.pictureBox1.TabIndex = 0
      Me.pictureBox1.TabStop = False
      '
      ' panel1
      '
      Me.panel1.Location = New System.Drawing.Point(8, 168)
      Me.panel1.Name = "panel1"
      Me.panel1.Size = New System.Drawing.Size(144, 144)
      Me.panel1.TabIndex = 1
      '
      ' button1
      '
      Me.button1.Location = New System.Drawing.Point(200, 176)
      Me.button1.Name = "button1"
      Me.button1.Size = New System.Drawing.Size(88, 24)
      Me.button1.TabIndex = 2
      Me.button1.Text = "Open"
      '
      ' button2
      '
      Me.button2.Location = New System.Drawing.Point(200, 216)
      Me.button2.Name = "button2"
      Me.button2.Size = New System.Drawing.Size(88, 24)
      Me.button2.TabIndex = 2
      Me.button2.Text = "Save"
      '
      ' button3
      '
      Me.button3.Location = New System.Drawing.Point(200, 256)
      Me.button3.Name = "button3"
      Me.button3.Size = New System.Drawing.Size(88, 24)
      Me.button3.TabIndex = 2
      Me.button3.Text = "Exit"
      '
      ' timer1
      '
      Me.timer1.Enabled = True
      Me.timer1.Interval = 250
      '
      ' Form1
      '
      Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
      Me.ClientSize = New System.Drawing.Size(328, 325)
      Me.Controls.Add(button1)
      Me.Controls.Add(panel1)
      Me.Controls.Add(pictureBox1)
      Me.Controls.Add(button2)
      Me.Controls.Add(button3)
      Me.Name = "Form1"
      Me.Text = "Form1"
      Me.ResumeLayout(False)
    End Sub 'InitializeComponent
#End Region
 
 
    '/ <summary>
    '/ The main entry point for the application.
    '/ </summary>
    <STAThread()> _
    Shared Sub Main()
      Application.Run(New Form1)
    End Sub 'Main
 
 
    Private Sub panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles panel1.Paint
      If cp Is Nothing Then
        Return
      End If
      Dim y As Single
      For y = 0 To 15
        Dim x As Single
        For x = 0 To 15
          Dim c As Color = Color.Black
          If 16 * y + x < cp.Entries.Length Then
            c = cp.Entries(CInt(16 * y + x))
          End If
          Dim sb As New SolidBrush(Color.FromArgb(255, c))
          Dim w As Single = CSng(Me.panel1.Width) / 16
          Dim h As Single = CSng(Me.panel1.Height) / 16
          e.Graphics.FillRectangle(sb, w * x, h * y, w, h)
          If c.A <> 255 Then
            If showTrans Then
              e.Graphics.DrawRectangle(Pens.Black, w * x, h * y, w - 1, h - 1)
            Else
              e.Graphics.DrawRectangle(Pens.White, w * x, h * y, w - 1, h - 1)
            End If
          End If
          sb.Dispose()
        Next x
      Next y
    End Sub 'panel1_Paint
 
 
    Private Sub panel1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles panel1.MouseMove
      Dim y As Integer = CInt(CSng(e.Y) / (CSng(Me.panel1.Width) / 16.0F))
      Dim x As Integer = CInt(CSng(e.X) / (CSng(Me.panel1.Height) / 16.0F))
      CurrentEntry = CInt(16 * y + x)
      If Not (cp Is Nothing) Then
        If CurrentEntry >= cp.Entries.Length Then
          CurrentEntry = cp.Entries.Length - 1
        End If 'Little bit of diagnostic for the palette chooser below
      End If 'System.Diagnostics.Trace.WriteLine(string.Format("{0},{1}, adjusted={4},{5} entry={2} Colour={3}",e.X,e.Y,CurrentEntry,cp.Entries[CurrentEntry].ToString(),x,y));
    End Sub 'panel1_MouseMove
 
 
    Private Sub panel1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles panel1.Click
      'Creates a new GIF image with a modified colour palette
      If Not (cp Is Nothing) Then
        'Create a new 8 bit per pixel image
        Dim bm As New Bitmap(_gifImage.Width, _gifImage.Height, PixelFormat.Format8bppIndexed)
        'get it's palette
        Dim ncp As ColorPalette = bm.Palette
 
        'copy all the entries from the old palette removing any transparency
        Dim n As Integer = 0
        Dim c As Color
        For Each c In cp.Entries
          ncp.Entries(n) = Color.FromArgb(255, c)
          n += 1
        Next c
        'Set the newly selected transparency
        ncp.Entries(CurrentEntry) = Color.FromArgb(0, cp.Entries(CurrentEntry))
        're-insert the palette
        bm.Palette = ncp
 
        'now to copy the actual bitmap data
        'lock the source and destination bits
        Dim src As BitmapData = CType(_gifImage, Bitmap).LockBits(New Rectangle(0, 0, _gifImage.Width, _gifImage.Height), ImageLockMode.ReadOnly, _gifImage.PixelFormat)
        Dim dst As BitmapData = bm.LockBits(New Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.WriteOnly, bm.PixelFormat)
 
        If (True) Then
          'steps through each pixel
          Dim y As Integer
          For y = 0 To _gifImage.Height - 1
            Dim x As Integer
            For x = 0 To _gifImage.Width - 1
              'transferring the bytes
              Marshal.WriteByte(dst.Scan0, dst.Stride * y + x, Marshal.ReadByte(src.Scan0, src.Stride * y + x))
            Next x
          Next y
        End If
        'all done, unlock the bitmaps
        CType(_gifImage, Bitmap).UnlockBits(src)
        bm.UnlockBits(dst)
 
        'clear out the picturebox
        Me.pictureBox1.Image = Nothing
        _gifImage.Dispose()
        'set the new image in place
        _gifImage = bm
        cp = _gifImage.Palette
        Me.pictureBox1.Image = _gifImage
      End If
    End Sub 'panel1_Click
 
 
    Private Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click
      Dim dlg As New OpenFileDialog
      dlg.Filter = "GIF files|*.GIF"
      If dlg.ShowDialog() = DialogResult.OK Then
        _gifImage = Image.FromFile(dlg.FileName)
        Me.pictureBox1.Image = _gifImage
        cp = _gifImage.Palette
        Me.panel1.Invalidate()
      End If
    End Sub 'button1_Click
 
 
    Private Sub button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button2.Click
      Dim dlg As New SaveFileDialog
      dlg.Filter = "GIF files|*.gif"
      dlg.DefaultExt = ".gif"
      dlg.AddExtension = True
      If dlg.ShowDialog() = DialogResult.OK Then
        _gifImage.Save(dlg.FileName, ImageFormat.Gif)
      End If
    End Sub 'button2_Click
 
 
    Private Sub button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button3.Click
      Application.Exit()
    End Sub 'button3_Click
 
    Private showTrans As Boolean
 
 
    Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer1.Tick
      showTrans ^= True
      Dim g As Graphics = Me.panel1.CreateGraphics()
      'I do this rather than invalidate the panel because
      'the panel draws its background ans so flickers horribly.
      Dim pe As New PaintEventArgs(g, New Rectangle(0, 0, Me.panel1.Width, Me.panel1.Height))
      Me.panel1_Paint(Me, pe)
      g.Dispose()
    End Sub 'timer1_Tick
  End Class 'Form1
End Namespace 'TransparentGifCreator
 
Figure 2 shows the application in action.
Figure 2: Before and after changing the transparent colour.
SHAILJA
 
The loginbox won't be displayed, because the extra "Member area" isn't activated!
WATCH AND CALENDER
 

SEARCH ON THIS PAGE
 


CONTACT US:
 
NAME : SANDEEP SINGH
ADDRESS: SHAHBAD DAULAT PUR DELHI 110042
PH NO: 09250532021
E-MAIL: sandeep9148@gmail.com
sandeep9148@ymail.com
govind9148@gmail.com
WEB : www.shailjasandeep.page.tl
www.shailjasandeep.webs.com
www.shailjasandeep.com
Owner of shailjasandeep.page.tl
Movies on shailjasandeep.page.tl
 
Now everyone can watch online exciting movies on the shailjasandeep.page.tl thanks for supporting...... ©copyright to shailjasandeep.page,tl

Dummies Book - Shailjasandeep.page.tl
 
Today, there have been 5 visitors (10 hits) on this page!


This website was created for free with Own-Free-Website.com. Would you also like to have your own website?
Sign up for free