none
C#載入圖檔繪圖,無法從具備索引像素格式的影像中建立圖形物件 RRS feed

  • 問題

  • 請問我想用c#載入一張圖檔到pictureBox中隨意繪圖

    但是載入的是副檔名是 .bmp 時 會出現

    無法從具備索引像素格式的影像中建立圖形物件 (Graphic Object)。

    請問遇到此問題時該如何解決?我才能載入.bmp檔進行繪圖。

    以下是我的程式碼

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Drawing.Text;
    using System.Text.RegularExpressions;
    
    
    
    namespace load_picture
    {
        public partial class Form1 : Form
        {
            int x0, y0;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                Bitmap bitmap_test = null;
    
                OpenFileDialog file = new OpenFileDialog();
    
                
    
                if (file.ShowDialog() != DialogResult.Cancel)
                {
                    
    
                    this.textBox2.Text = file.FileName;
    
                    
    
                    bitmap_test = new Bitmap(textBox2.Text);
    
                   
    
                    
                        pictureBox1.Image = bitmap_test;
                       
                   
    
                    
                }
            }
    
            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                x0 = e.X;
                y0 = e.Y;
            }
    
            private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    Graphics g = Graphics.FromImage(pictureBox1.Image);
                    g.DrawLine(Pens.Red, x0, y0, e.X, e.Y);
                    x0 = e.X;
                    y0 = e.Y;
                    pictureBox1.Refresh();
                }
                
            }
    
        }
    }
    

    2015年5月29日 下午 12:48

解答

  • ...

    在 Windows 內正確繪圖觀念應該先看清楚 Windows 的色階,在不同色階下,你只能處理該色階的圖檔。

    在全彩下,只能處理 24/32 bits 圖檔。

    因此,低色階圖形需

    1. 開新的全彩圖,例如 New Bitmap(寬, 高)

    2. 從新全彩圖產生 Graphics 物件。

    3. 將低色階圖,用 Graphics.DrawImage 畫到新全彩圖。

    4. 關閉低色階圖。

    5. 在新全彩圖做圖。

    6. 若需降色階,則開新低色階圖,請參考 Bitmap 建構函式多型,做遞色運算,若不需要降色階可跳過。

    7. 存檔。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 max79411 2015年6月3日 上午 06:08
    2015年6月1日 下午 03:30

所有回覆

  •             if (file.ShowDialog() != DialogResult.Cancel)
                {
                    string sName = file.FileName;
                    this.textBox2.Text = file.FileName;
                    this.textBox2.Text = sName;
                    bitmap_test = new Bitmap(sName);
                    pictureBox1.Image = bitmap_test;
                }
    確定圖有載入嗎...

    2015年5月29日 下午 11:32
    • 已提議為解答 Howard_cmit 2015年6月1日 上午 03:13
    2015年5月30日 下午 12:09
  • 您可以參考這篇文件的做法:Solution for "A Graphics Object cannot be Created from an Image that has an Indexed Pixel Format"

    這個方式真不錯,

    以前不知道,都還傻傻的自己轉。底下是自己轉的code.

          int w = gray.Width;
          int h = gray.Height;
          BitmapData grayData = gray.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
          BitmapData colorData = color.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
          try
          {
            unsafe
            {
              byte* pGray = (byte*)(grayData.Scan0.ToPointer());
              byte* pColor = (byte*)(colorData.Scan0.ToPointer());
              int idx = 0;
              int idx2 = 0;
              //System.Diagnostics.Trace.WriteLine(string.Format("grayData.Stride = {0} colorData.Stride = {1}", grayData.Stride, colorData.Stride));
              for (int y = 0; y < h; y++)
              {
                for (int x = 0; x < w; x++)
                {
                  idx = x + y * grayData.Stride;
                  idx2 = 3 * x + y * colorData.Stride;
                  pColor[idx2] = pGray[idx];
                  pColor[idx2 + 1] = pGray[idx];
                  pColor[idx2 + 2] = pGray[idx];
                }
              }
            }
          }
          finally
          {
            gray.UnlockBits(grayData);
            color.UnlockBits(colorData);
          }

    2015年6月1日 上午 03:18
  • ...

    在 Windows 內正確繪圖觀念應該先看清楚 Windows 的色階,在不同色階下,你只能處理該色階的圖檔。

    在全彩下,只能處理 24/32 bits 圖檔。

    因此,低色階圖形需

    1. 開新的全彩圖,例如 New Bitmap(寬, 高)

    2. 從新全彩圖產生 Graphics 物件。

    3. 將低色階圖,用 Graphics.DrawImage 畫到新全彩圖。

    4. 關閉低色階圖。

    5. 在新全彩圖做圖。

    6. 若需降色階,則開新低色階圖,請參考 Bitmap 建構函式多型,做遞色運算,若不需要降色階可跳過。

    7. 存檔。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 max79411 2015年6月3日 上午 06:08
    2015年6月1日 下午 03:30