2010-04-07 81 views
3

我試圖編輯8bpp的像素。由於這PixelFormat索引,我知道它使用顏色表來映射像素值。儘管我可以通過將位圖轉換爲24bpp來編輯位圖,但8bpp編輯速度更快(13ms vs 3ms)。但是,訪問8bpp位圖時更改每個值會導致一些隨機的rgb顏色,即使PixelFormat保持8bpp。編輯8bpp索引位圖

我目前正在開發在C#和算法如下:

(C#)在8bpp的

2-

1-加載原始位圖與和8bpp的創建空臨時位圖與原始大小相同

這兩個位圖的3-LockBits以及使用P/Invoke調用每個BitmapData對象的Scan0的C++方法。 (I使用C++方法通過位圖的像素迭代時,因爲它提供更好的性能)

(C++)

4-創建INT根據一些參數[256]調色板和通過使編輯臨時位圖字節原始像素值通過調色板。

(C#)

5- UnlockBits。

我的問題是如何編輯像素值,而不會有奇怪的RGB顏色,甚至更好,編輯8bpp位圖的顏色表?

回答

1

您是否試過加載System.Drawing.Image?該課程可讓您訪問調色板。一旦設置了調色板,您就可以將System.Drawing.Image作爲System.Drawing.Bitmap包裝起來。

我不確定System.Drawing.BitMap.SetPixel()如何與索引的彩色圖像一起使用。它可能會嘗試將其映射到調色板中最接近的顏色。

+0

感謝您的回答。我知道我可以通過更改位圖的調色板屬性來修改位圖的調色板。但是這樣做太慢了。我希望有人能告訴我如何訪問顏色表指針,以便我可以直接修改它。 SetPixel不起作用,也非常緩慢。 我不明白爲什麼像素被分配了rgb顏色,當我將其值從0(黑色)更改爲100(應該是灰色,但是是紅色)。 – 2010-04-07 15:20:15

+0

嗯。 'Bitmap'從'Image'繼承,因此具有相同的調色板。你可以簡單地用'bm2.Palette = bm1.Palette'複製調色板。 – Nyerguds 2018-01-22 21:48:04

10

有沒有必要進入C++土地或使用P/Invoke; C#支持指針和不安全的代碼完美無瑕;我甚至可能會猜測這是造成你的問題。

顏色可能來自默認的調色板。你會發現改變調色板應該不會很慢。這是我做的,以創建一個灰度調色板:

image = new Bitmap(_size.Width, _size.Height, PixelFormat.Format8bppIndexed); 
ColorPalette pal = image.Palette; 
for(int i=0;i<=255;i++) { 
    // create greyscale color table 
    pal.Entries[i] = Color.FromArgb(i, i, i); 
} 
image.Palette = pal; // you need to re-set this property to force the new ColorPalette 
+0

如何將新調色板應用於舊圖像?如何改變舊圖像的大小? – Leon 2012-07-18 10:55:35

+1

只需設置「調色板」屬性。調整圖像大小是不同的,在右邊的dumensions的新圖像上使用'Graphics.DrawImage'。 – Dai 2013-05-28 06:59:55

+0

Graphics.DrawImage在索引的像素格式上不受支持,並且轉換爲非索引會否定使用索引格式的速度優勢。 – Nuzzolilo 2016-02-17 00:44:21

2

試想一下,你的索引8ppp graysacle存儲的線性陣列在數據B(速度)

試試這個代碼:

//Create 8bpp bitmap and look bitmap data 
bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed); 
bmp.SetResolution(horizontalResolution, verticalResolution); 
bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); 

//Create grayscale color table 
ColorPalette palette = bmp.Palette; 
for (int i = 0; i < 256; i++) 
    palette.Entries[i] = Color.FromArgb(i, i, i); 
bmp.Palette = palette; 

//write data to bitmap 
int dataCount = 0; 
int stride = bmpData.Stride < 0 ? -bmpData.Stride : bmpData.Stride; 
unsafe 
{ 
    byte* row = (byte*)bmpData.Scan0; 
    for (int f = 0; f < height; f++) 
    { 
     for (int w = 0; w < width; w++) 
     { 
      row[w] = (byte)Math.Min(255, Math.Max(0, dataB[dataCount])); 
      dataCount++; 
     } 
     row += stride; 
    } 
} 

//Unlock bitmap data 
bmp.UnlockBits(bmpData); 
0

我沒有足夠的聲望評論Paul Ruane的帖子,但不得不說他將文件加載到System.Drawing.Image的方法,改變調色板並將生成的圖像發送到System.Drawing.Bitmap以保存實際的作品。

>如果我直接通過Image進行保存,則更改將被丟棄。

>如果通過Bitmap保存,則更改將保留。