locked
A Graphics object cannot be created from an image that has an indexed pixel format. RRS feed

  • Pergunta

  • I have used this Overlay function with tif files I create. However, when I download a "real" tif image from our repository, I get the subject line error.

    1. What is an indexed pixel format?

    2. Can I convert it in my code to an acceptible format? or use a different object to accomplish the text overlay header?

            public void Overlay(string fn, string accn)
            {
                string dir = Path.GetDirectoryName(fn);
                string temp = Path.Combine(dir, "temp.tif");
                File.Delete(temp);
                File.Move(fn, temp);
                string msg = "Accn:" + accn;
                FileStream fs = File.Open(temp, FileMode.Open, FileAccess.Read);
                Bitmap bm = (Bitmap)Bitmap.FromStream(fs);
                Graphics graphics = Graphics.FromImage(bm);
                SolidBrush brush = new SolidBrush(Color.Black);
                Font font = new Font("Courier New", 20, FontStyle.Bold);
                Rectangle rect = new Rectangle(8, 8, 300, 80);
                graphics.DrawString(msg, font, brush, rect);
                fs.Close();            
                bm.Save(fn);            
            }
    Thanks,

    Jon Jacobs
    Not sent from my iphone, because I don't have one.

    sábado, 20 de abril de 2013 01:55

Respostas

  • An indexed image is an image with a palette.  GDI+ doesn't support drawing to indexed images.  Draw your indexed image on a non-indexed image and then draw your text on the non-indexed image:

          Bitmap newBitmap = new Bitmap(bm.Width, bm.Height);
          
    Graphics graphics = Graphics.FromImage(newBitmap);
          graphics.DrawImage(bm, 0, 0);

    • Sugerido como Resposta Jason Dot Wang terça-feira, 23 de abril de 2013 04:26
    • Marcado como Resposta Jason Dot Wang terça-feira, 30 de abril de 2013 08:36
    sábado, 20 de abril de 2013 18:47
  • Hi.

    When a "normal" pixel format works somewhat like this: 

    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB


    An indexed one defines a palette of colors as an array, and then references those indexes instead of defining a color at each pixel co-ordinate, effectively saving memory and disk space.

    P[] = { RGB, RGB, RGB, RGB, RGB }
    
    P[0] P[3] P[0] P[2] P[1]
    
    P[1] P[2] P[4] P[1] P[0]
    
    P[2] P[3] P[1] P[2] P[2]
    
    P[0] P[3] P[2] P[3] P[1]
    
    P[4] P[3] P[0] P[2] P[1]

    About your problem, I'm guessing that the exception gets thrown at this line: 

    Graphics graphics = Graphics.FromImage(bm);

    According to the documentation of Graphics.FromImage(the remarks section), you can save the indexed image as another format by using the Save(String, ImageFormat) method and then retrieve a Graphics object for the new image.

    So go ahead and try that! Convert the indexed TIFF to, say, PNG, and then call Graphics.FromImage on the converted image.


    Teo Selenius

    • Marcado como Resposta Jon Q Jacobs segunda-feira, 22 de abril de 2013 13:28
    sábado, 20 de abril de 2013 05:22

Todas as Respostas

  • Hi.

    When a "normal" pixel format works somewhat like this: 

    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB
    
    RGB RGB RGB RGB RGB


    An indexed one defines a palette of colors as an array, and then references those indexes instead of defining a color at each pixel co-ordinate, effectively saving memory and disk space.

    P[] = { RGB, RGB, RGB, RGB, RGB }
    
    P[0] P[3] P[0] P[2] P[1]
    
    P[1] P[2] P[4] P[1] P[0]
    
    P[2] P[3] P[1] P[2] P[2]
    
    P[0] P[3] P[2] P[3] P[1]
    
    P[4] P[3] P[0] P[2] P[1]

    About your problem, I'm guessing that the exception gets thrown at this line: 

    Graphics graphics = Graphics.FromImage(bm);

    According to the documentation of Graphics.FromImage(the remarks section), you can save the indexed image as another format by using the Save(String, ImageFormat) method and then retrieve a Graphics object for the new image.

    So go ahead and try that! Convert the indexed TIFF to, say, PNG, and then call Graphics.FromImage on the converted image.


    Teo Selenius

    • Marcado como Resposta Jon Q Jacobs segunda-feira, 22 de abril de 2013 13:28
    sábado, 20 de abril de 2013 05:22
  • An indexed image is an image with a palette.  GDI+ doesn't support drawing to indexed images.  Draw your indexed image on a non-indexed image and then draw your text on the non-indexed image:

          Bitmap newBitmap = new Bitmap(bm.Width, bm.Height);
          
    Graphics graphics = Graphics.FromImage(newBitmap);
          graphics.DrawImage(bm, 0, 0);

    • Sugerido como Resposta Jason Dot Wang terça-feira, 23 de abril de 2013 04:26
    • Marcado como Resposta Jason Dot Wang terça-feira, 30 de abril de 2013 08:36
    sábado, 20 de abril de 2013 18:47
  • Hi, how do I do this part:  Convert the indexed TIFF to, say, PNG, and then call Graphics.FromImage on the converted image.

    Thank you

    segunda-feira, 6 de janeiro de 2020 17:11
  • Hi, how do I do this part:  Convert the indexed TIFF to, say, PNG, and then call Graphics.FromImage on the converted image.

    Thank you

    Based in John Wien's example above, you dont need to declare anything again with .fromimage,  you have the graphics surface there already with the original tiff drawn on it. You can just continue to draw on that graphic. If that is what you want to do.

    Here is an example of saving the original tif as png similar to what John showed. 

    Then the example opens the saved png and draws "tommytwotrain" on it with graphics from image.

    You could also draw on the same g after saving it etc.

    PS You should try to start a new thread with your own question instead of adding to an old thread.

    :)

    public partial class Form3 : Form { private Bitmap MemoryBmp; public Form3() { InitializeComponent(); } private void Form3_Load(object sender, EventArgs e) { { // draw a new copy of the tif and save as png using (var tifBmp = new Bitmap(@"C:\bitmaps\drg mak cover front 600.tif")) using (Graphics g = Graphics.FromImage(tifBmp) ) {

    g.DrawImage(tifBmp, 0, 0, bitmap.Width, bitmap.Height); //g.DrawImage(tifBmp, 0, 0); tifBmp.Save(@"c:\test\tifBmp1.png"); } // open the saved png file, make a graphics surface, // draw on the graphics, and then show in the form MemoryBmp = new Bitmap(@"c:\test\tifBmp1.png"); using (Graphics g = Graphics.FromImage(MemoryBmp)) { g.DrawString("tommytwotrain", new Font("arial", 18, FontStyle.Bold), Brushes.Lime, 10, 600); this.BackgroundImage = MemoryBmp; this.BackgroundImageLayout = ImageLayout.Zoom; } } } }



    • Editado tommytwotrain segunda-feira, 6 de janeiro de 2020 23:18 add size drawimage
    segunda-feira, 6 de janeiro de 2020 18:56
  • [

    [HttpPost]
            public ActionResult Index(string text, int text1)
          {
                
                DirectoryInfo dir = new DirectoryInfo(@"C:\Users\name\Desktop\images");
                FileInfo[] files = dir.GetFiles();
                string value = text;
                int value1 = text1;
                //string file = Path.GetFileNameWithoutExtension(postedFile.FileName) + ".png";
                foreach (FileInfo file in files)
                {
                    // string newfile = Path.GetFileNameWithoutExtension(file.FileName) + ".png";
                    //if (postedFile != null)
                    //{
                    // Load document
                 
                    using (Bitmap bitmap = new Bitmap(file.FullName))
                    {
                        Bitmap tempBitmap = new Bitmap(bitmap.Width, bitmap.Height);
                        using (Graphics graphics = Graphics.FromImage(tempBitmap))
                        {
                            graphics.DrawImage(bitmap, 0, 0);
                           // graphics.DrawLine();
                            Brush brush = new SolidBrush(Color.Black);
                            Font font = new Font("Arial", 10, FontStyle.Italic, GraphicsUnit.Pixel);
                            SizeF textSize = new SizeF();
                            textSize = graphics.MeasureString(value, font);
                            Point position = new Point(bitmap.Width - ((int)textSize.Width + 30), bitmap.Height - ((int)textSize.Height + 10));
                            graphics.DrawString((value + value1++), font, brush, position);
                            using (MemoryStream mStream = new MemoryStream())
                            {
                                mStream.Position = 0;
                                tempBitmap.Save(mStream, ImageFormat.Tiff);
                                string _path = Path.Combine(Server.MapPath("~/UploadedFolders"), file.Name);
                                tempBitmap.Save(_path);
                                
                            }
                        }
                    }
    
    
    
                }
           
                return View();
            }
    

    the issue here is the resulting image is extremaly small. Is there a way to save it as original size.

    or how can i convert everything in that directory to png then edit.

    thank you.




    • Editado HelpIsNice segunda-feira, 6 de janeiro de 2020 20:06
    segunda-feira, 6 de janeiro de 2020 20:05