none
請問大大們 ,關於讀取灰階影像(bmp)問題 RRS feed

  • 問題

  • 請問大大們:

    小弟在網路上搜尋都是搜尋到讀取彩色圖片的Pixel值,但我要讀取灰階影像裡的Pixel值卻找不太到~~~

    之前是用GetPixel指令,但速度太慢!請教各位大大要如何才能讀取灰階影像的Pixel值???

    或者有範例程式可以讓小弟學習,請高手大大們指導!


    2012年3月14日 上午 10:54

解答

所有回覆

  • 2012年3月14日 上午 11:07
    版主
  • 以下是我依搜尋到的Code 原來是針對彩色,而我將Code改成針對灰階,但出現了Bug,而我也不知道這樣對不對,要

    將灰階影像轉成2維陣列!

    //讀取影像資料:利用指標將影像轉換成矩陣形式
            public static int[,] LoadImageData(Bitmap Original_input)
            {
                // Step 1: 先鎖住存放圖片的記憶體
                BitmapData inputData = Original_input.LockBits(new Rectangle(0, 0, Original_input.Width, Original_input.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

                //Bitmap 元件的 scan 寬度(單位 byte)
                int stride = inputData.Stride;

                // Step 2: 取得像點資料的起始位址
                System.IntPtr Scan0 = inputData.Scan0;

                //    #region 計算每行有幾個 Padding bytes 長度的計算方式如下:
                //    // 計算每行的像點所佔據的byte 總數
                int ByteNumber_Width = Original_input.Width;

                // 計算每一行後面幾個 Padding bytes
                int ByteOfSkip = stride - ByteNumber_Width;

                int Height = Original_input.Height;
                int Width = Original_input.Width;
                int[,] rgbData = new int[Width, Height];

                // Step 3: 直接利用指標, 把影像資料取出來
                //         請注意先取 B 然後是 G, 最後才是 R
                //         從低位元到高位元的排列方式為 B,G,R.

                unsafe
                {
                    byte* p = (byte*)(void*)Scan0;
                    for (int y = 0; y < Height; y++)
                    {
                        for (int x = 0; x < Width; x++)
                        {
                            rgbData[x, y] = p[0];
                            ++p;                       
                        }
                        p += ByteOfSkip;
                        // 跳過剩下的 Padding bytes
                    }
                }
                Original_input.UnlockBits(inputData);

                return rgbData;             //將rgbData傳回呼叫它的地方
            }

    2012年3月14日 下午 12:18
  •  int ByteNumber_Width = bitmap.Width * 3;

    這樣後面計算的 ByteOfSkip 才會是正確的

    然後內層迴圈的++p要改成p +=3;


    以下為簽名檔,如果你愛拉椅子坐那就是你的問題。
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度

    • 已標示為解答 超嫩新手 2012年3月15日 上午 08:13
    2012年3月14日 下午 03:33
  • 最好一進來時,先判定是否為灰階(8bit)的格式。

    LockBits中的PixelFormat.Format24bppRgb要改成PixelFormat.Format8bppIndexed

    然後你的調色盤也要改一下,出來才會是灰階的,

    ColorPalette grayPalette = Original_input.Palette;

    for (int i = 0; i < 256; i++)
    {
       grayPalette .Entries[i] = Color.FromArgb(i, i, i);
     }

    Original_input.Palette = grayPalette;


    • 已編輯 Howard_cmit 2012年3月15日 上午 12:47
    • 已標示為解答 超嫩新手 2012年3月15日 上午 08:13
    2012年3月15日 上午 12:46