question

Chocolade-4229 avatar image
0 Votes"
Chocolade-4229 asked Castorix31 commented

How can I add extra text as new part of existing image gif?

I have this image in the original :

141067-radimage0.gif

I want to edit the gif by code and to add a text to it at the bottom and make the text as part of the gif image.

For example like this :

141075-red1.jpg

I marked with red the gray background and the text I want to add to the first image, this is what I mean the gray part and the text the time and date.

Marked in red at the bottom to show what I mean by adding the gray background and the text.

The text at the bottom the date and time I want to add it to the gif image the first gif image I show here only the text or also part of the gray background but something like the second image.

To add more pixels or something as the gray background at the bottom and then write on it the text the time and date and then to save the original gif with the made changes.

The second image here is just example of what I want to archive on the first image.

The text is not matter now what it will be but I want to be able to edit the gif add some text at the bottom as part of it and save the gif.

What I tried so far :

Created a new class with this code :

 using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Text;
 using System.Text;
    
 namespace Wpf_Download_Files
 {
     class DrawOnImage
     {
         public Image DrawText(String text, String subText, Image img)
         {
             var textColor = Color.Black;
             var backColor = Color.Transparent;
    
             var textFont = new Font("Arial", 15);
             Brush textBrush = new SolidBrush(textColor);
    
             var subTextFont = new Font("Arial", 7);
             Brush subTextBrush = new SolidBrush(textColor);
    
             //first, create a dummy bitmap just to get a graphics object
             img = new Bitmap(img);
             Graphics drawing = Graphics.FromImage(img);
    
             //measure the string to see how big the image needs to be
             SizeF textSize = drawing.MeasureString(text, textFont);
             SizeF subTextSize = drawing.MeasureString(subText, subTextFont);
    
             //free up the dummy image and old graphics object
             img.Dispose();
             drawing.Dispose();
    
             //create a new image of the right size
             img = new Bitmap(((int)textSize.Width + (int)subTextSize.Width) - ((int)textSize.Width / 3), (int)textSize.Height + 15);
    
             drawing = Graphics.FromImage(img);
             drawing.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
    
             //paint the background
             drawing.Clear(backColor);
    
             //Draw Text
             drawing.DrawString(text, textFont, textBrush, 5, 0);
    
             //Drawing Line
             var linePen = new Pen(Color.Black, 3);
             var height = (int)textSize.Height;
             var width = (int)textSize.Width;
    
             drawVerticalLine(drawing, linePen, 1, 0, height + 5);
             drawHorizontalLine(drawing, linePen, 0, height + 5, width / 3);
    
             //Darw Subtext
             drawing.DrawString(subText, subTextFont, subTextBrush, width / 3, height);
    
             drawing.Save();
    
             textBrush.Dispose();
             drawing.Dispose();
    
             return img;
         }
    
         private void drawHorizontalLine(Graphics graphics, Pen pen, int x, int y, int width)
         {
             graphics.DrawLine(pen, x, y, x + width, y);
         }
    
         private void drawVerticalLine(Graphics graphics, Pen pen, int x, int y, int height)
         {
             graphics.DrawLine(pen, x, y, x, y + height);
         }
     }
 }

And in the main form I did :

 public MainWindow()
         {
             InitializeComponent();
    
             System.Drawing.Image img =
                 System.Drawing.Image.FromFile(@"d:\Downloaded Images\Image0.gif");
             DrawOnImage drawonimage = new DrawOnImage();
             drawonimage.DrawText("Hello World", "utt 12345", img);



dotnet-csharpwindows-wpfwindows-forms
radimage0.gif (95.7 KiB)
red1.jpg (130.4 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


If you do not really want to alter the image, you can insert to your form some labels and other controls.


0 Votes 0 ·
Castorix31 avatar image
0 Votes"
Castorix31 answered Castorix31 commented

I forgot to mention that I'm using wpf not winforms if it's important.

A way in WPF :

 BitmapImage bi = new BitmapImage();
 bi.BeginInit();
 bi.UriSource = new Uri(@"E:\Hulk.gif", UriKind.RelativeOrAbsolute);
 bi.EndInit();
    
 string sText = "This is a text";
 int nTextHeight = 60;
 DrawingVisual drawingVisual = new DrawingVisual();
 using (DrawingContext drawingContext = drawingVisual.RenderOpen())
 {
     drawingContext.DrawImage(bi, new Rect(0, 0, bi.Width, bi.Height));
    
     Rect rect = new Rect(0, bi.Height, bi.Width, nTextHeight);
     drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightGray, new Pen(Brushes.Red, 2), rect);                   
    
     var formattedText = new FormattedText(sText, System.Globalization.CultureInfo.InvariantCulture,
         FlowDirection.LeftToRight,
         new Typeface("Arial"), 12, Brushes.Red);
     formattedText.TextAlignment = TextAlignment.Center;
     double nX = bi.Width / 2; 
     double nY = bi.Height + nTextHeight / 2;                    
     Point pt = new Point(nX, nY - formattedText.Height / 2);
     drawingContext.DrawText(formattedText, pt); 
 }
 RenderTargetBitmap bmp = new RenderTargetBitmap((int)bi.Width, (int)bi.Height + nTextHeight, 96, 96, PixelFormats.Pbgra32);
 bmp.Render(drawingVisual);
    
 GifBitmapEncoder gif = new GifBitmapEncoder();
 gif.Frames.Add(BitmapFrame.Create(bmp));                
 using (System.IO.Stream stm = System.IO.File.Create(@"E:\Hulk_2.gif"))
 {
     gif.Save(stm);
 }


· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Getting some errors.

On the line :

 var formattedText = new System.Windows.Media.FormattedText(sText, System.Globalization.CultureInfo.InvariantCulture,
                     FlowDirection.LeftToRight,
                     new Typeface("Arial"), 12, Brushes.Red);

Severity Code Description Project File Line Suppression State
Error CS0104 'Brushes' is an ambiguous reference between 'System.Drawing.Brushes' and 'System.Windows.Media.Brushes' Wpf Download Files D:\Csharp Projects\Wpf Download Files\DrawOnImage.cs 29 Active


So I tried to change it to Media :

 var formattedText = new System.Windows.Media.FormattedText(sText, System.Globalization.CultureInfo.InvariantCulture,
                     FlowDirection.LeftToRight,
                     new Typeface("Arial"), 12, System.Windows.Media.Brushes.Red);

Now everything is with green line say :

FormattedText is obsolete use PixelsPerDip override.




All the errors are only on the FormattredText :

  var formattedText = new System.Windows.Media.FormattedText(sText, System.Globalization.CultureInfo.InvariantCulture,
                     FlowDirection.LeftToRight,
                     new Typeface("Arial"), 12, System.Windows.Media.Brushes.Red);

0 Votes 0 ·

If I'm changing it to System.Drawing.Brushes :

 var formattedText = new System.Windows.Media.FormattedText(sText, System.Globalization.CultureInfo.InvariantCulture,
                     FlowDirection.LeftToRight,
                     new Typeface("Arial"), 12, System.Drawing.Brushes.Red);


Now I'm getting error :


Severity Code Description Project File Line Suppression State
Error CS0104 'Brushes' is an ambiguous reference between 'System.Drawing.Brushes' and 'System.Windows.Media.Brushes' Wpf Download Files D:\Csharp Projects\Wpf Download Files\DrawOnImage.cs 29 Active

0 Votes 0 ·

If you use WPF only, don't use Winforms namespaces like

  using System.Drawing;

Everything is in System.Windows.Media

0 Votes 0 ·

The complete method now with the FormattedText problem/s

https://pastebin.com/0RpLtprg

0 Votes 0 ·
Castorix31 avatar image
0 Votes"
Castorix31 answered Chocolade-4229 commented

For example =>

Original :
141068-hulk.gif

New :
141058-hulk2.gif

 System.Drawing.Image img = System.Drawing.Image.FromFile("E:\\Hulk.gif");
 int nWidth = img.Width;
 int nHeight = img.Height;
 int nTextHeight = 60;
    
 Bitmap bmp = new Bitmap(nWidth, nHeight + nTextHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 using (Graphics g = Graphics.FromImage(bmp))
 {
     g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
     g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
     g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
    
     g.DrawImage(img, new Rectangle(new Point(), img.Size), new Rectangle(new Point(), img.Size), GraphicsUnit.Pixel);
     string sText = "This is a text";
     using (Font font = new Font("Arial", 12, System.Drawing.FontStyle.Regular, GraphicsUnit.Point))
     {
         Rectangle rect = new Rectangle(0, nHeight, nWidth, nTextHeight);
         g.FillRectangle(System.Drawing.Brushes.LightGray, rect);
         g.DrawRectangle(Pens.Red, rect);
         StringFormat stringFormat = new StringFormat();
         stringFormat.Alignment = StringAlignment.Center;
         stringFormat.LineAlignment = StringAlignment.Center;
         g.DrawString(sText, font, Brushes.Red, rect, stringFormat);                   
     }
 }
    
 bmp.Save("E:\\Hulk2.gif", System.Drawing.Imaging.ImageFormat.Gif);
 // Test in a PictureBox
 pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
 pictureBox1.Image = bmp;



hulk.gif (28.0 KiB)
hulk2.gif (25.0 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Why I'm getting exception ?

In the class I did :

 public void DrawText(String text, String path)
         {
             Image img = System.Drawing.Image.FromFile(path);

Then using the text :

 string sText = text;


At the bottom :

 bmp.Save(path, System.Drawing.Imaging.ImageFormat.Gif);

The rest of the code is like in your answer I didnt change it and in the main form :

 DrawOnImage drawonimage = new DrawOnImage();
 drawonimage.DrawText("Hello World", @"d:\Downloaded Images\Radar\radImage0.gif");


This is a link for the class DrawOnImage full code with your answer :

https://pastebin.com/zdi31pgZ

The exception I'm getting when running the application :

System.Windows.Markup.XamlParseException: ''The invocation of the constructor on type 'Wpf_Download_Files.MainWindow' that matches the specified binding constraints threw an exception.' Line number '6' and line position '9'.'


Inner Exception :

ExternalException: A generic error occurred in GDI+.

0 Votes 0 ·

I forgot to mention that I'm using wpf not winforms if it's important.

0 Votes 0 ·