簡體   English   中英

如何使用GDI按像素強度將位圖轉換為灰度?

[英]How to convert bitmap to grayscale by pixel intensity using GDI?

我正在尋找如何使用GDI(而不是GDI +)將32位位圖轉換為灰度的簡單解決方案。 是否有可能通過更改位圖的托盤或其他東西?

當然Delphi中有很多像這樣的例子,但是我正在尋找一個WinAPI函數,它可以在沒有迭代的情況下執行此操作。

我沒有找到任何單一的GDI功能。 大衛在評論中提到的最簡單的方法是掃描每一行並計算像素顏色。 您正在尋找的可能是luminance公式。

該公式的變化很少,在下面的例子中,我使用了ITU建議的那個,參見this document第2.5.1節。 正如我在某處找到的那樣,這個公式甚至可以用於熟知的Adobe Photoshop。 以下代碼示例僅支持並期望24位像素格式位圖作為輸入:

procedure BitmapGrayscale(ABitmap: TBitmap);
type
  PPixelRec = ^TPixelRec;
  TPixelRec = packed record
    B: Byte;
    G: Byte;
    R: Byte;
  end;
var
  X: Integer;
  Y: Integer;
  Gray: Byte;
  Pixel: PPixelRec;
begin
  for Y := 0 to ABitmap.Height - 1 do
  begin
    Pixel := ABitmap.ScanLine[Y];
    for X := 0 to ABitmap.Width - 1 do
    begin
      Gray := Round((0.299 * Pixel.R) + (0.587 * Pixel.G) + (0.114 * Pixel.B));
      Pixel.R := Gray;
      Pixel.G := Gray;
      Pixel.B := Gray;
      Inc(Pixel);
    end;
  end;
end;

您可以創建一個調色板DIB截面,每像素8位和256種顏色,並將調色板初始化為灰色{0,0,0},{1,1,1},... {255,255,255}的陰影。

此位圖中的單個GDI BitBlt將使原始圖像變灰。 這是代碼片段(用C ++,ATL和WTL - 但你應該明白這一點)。

CWindowDC DesktopDc(NULL);
CDC BitmapDc;
ATLVERIFY(BitmapDc.CreateCompatibleDC(DesktopDc));
CBitmap Bitmap;
CTempBuffer<BITMAPINFO> pBitmapInfo;
const SIZE_T nBitmapInfoSize = sizeof (BITMAPINFO) + 256 * sizeof (RGBQUAD);
pBitmapInfo.AllocateBytes(nBitmapInfoSize);
ZeroMemory(pBitmapInfo, nBitmapInfoSize);
pBitmapInfo->bmiHeader.biSize = sizeof pBitmapInfo->bmiHeader;
pBitmapInfo->bmiHeader.biWidth = 320;
pBitmapInfo->bmiHeader.biHeight = 240;
pBitmapInfo->bmiHeader.biPlanes = 1;
pBitmapInfo->bmiHeader.biBitCount = 8;
pBitmapInfo->bmiHeader.biCompression = BI_RGB;
pBitmapInfo->bmiHeader.biSizeImage = 240 * 320;
pBitmapInfo->bmiHeader.biClrUsed = 256;
pBitmapInfo->bmiHeader.biClrImportant = 256;
for(SIZE_T nIndex = 0; nIndex < 256; nIndex++)
{
    pBitmapInfo->bmiColors[nIndex].rgbRed = (BYTE) nIndex;
    pBitmapInfo->bmiColors[nIndex].rgbGreen = (BYTE) nIndex;
    pBitmapInfo->bmiColors[nIndex].rgbBlue = (BYTE) nIndex;
}
Bitmap.Attach(CreateDIBSection(DesktopDc, pBitmapInfo, 0, DIB_RGB_COLORS, NULL, 0));
ATLVERIFY(Bitmap);
BitmapDc.SelectBitmap(Bitmap);
////////////////////////////////////////////////
// This is what greys it out:
ATLVERIFY(BitBlt(BitmapDc, 0, 0, 320, 240, DesktopDc, 0, 0, SRCCOPY));
////////////////////////////////////////////////
ATLVERIFY(BitBlt(DesktopDc, 0, 240, 320, 240, BitmapDc, 0, 0, SRCCOPY));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM