2011-12-19 9 views
7

मैं 32-बिट बिटमैप को जीडीआई (जीडीआई + नहीं) का उपयोग करके ग्रेस्केल में कनवर्ट करने का सरल समाधान ढूंढ रहा हूं। क्या कोई संभावना है बिटमैप की पालीट या कुछ बदलकर?जीडीआई का उपयोग कर पिक्सेल तीव्रता द्वारा बिटमैप को ग्रेस्केल में कैसे परिवर्तित करें?

बेशक डेल्फी में this one जैसे कई उदाहरण हैं, लेकिन मैं एक WinAPI फ़ंक्शन ढूंढ रहा हूं जो लाइनों के माध्यम से पुनरावृत्ति के बिना ऐसा करेगा।

+2

मुझे एकल जीडीआई फ़ंक्शन के बारे में पता नहीं है जो न ही पैलेट रूपांतरण के बारे में करेगा, लेकिन आपके द्वारा वर्णित लिंक से तीसरा फ़ंक्शन ऐसा करता है। मुझे लगता है कि आप प्रदर्शन से डरते हैं ना? – TLama

+0

यह न केवल प्रदर्शन के बारे में है, मैं एक आसान समाधान ढूंढ रहा हूं (शायद पैलेट या कुछ परिवर्तित करके)। –

+0

32-बिट बिटमैप में पैलेट नहीं है। – MBo

उत्तर

8

मुझे ऐसा कोई भी जीडीआई फ़ंक्शन नहीं मिला है। डेविड के रूप में उनकी टिप्पणी में उल्लेख किया गया सबसे आसान तरीका, प्रत्येक पंक्ति को स्कैन करना और पिक्सेल रंगों की गणना करना है। आप जो खोज रहे हैं वह शायद luminance फॉर्मूला है।

इस सूत्र के कुछ भिन्नताएं हैं और निम्न उदाहरण में मैंने ITU द्वारा अनुशंसित एक का उपयोग किया है, this document अनुभाग 2.5.1 देखें। जैसा कि मैंने कहीं पाया, इस सूत्र का उपयोग किया जाता है उदा। यहां तक ​​कि प्रसिद्ध एडोब फोटोशॉप द्वारा भी। निम्न उदाहरण कोड का समर्थन करता है और उम्मीद करता है केवल 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; 
+3

धन्यवाद TLama, ऐसा लगता है कि इसके लिए वास्तव में कोई WinAPI फ़ंक्शन नहीं है। –

5

आप एक paletted डीआईबी धारा, पिक्सेल प्रति 8 बिट और 256 रंगों बना सकते हैं और भूरे रंग {0 को पैलेट प्रारंभ , 0, 0}, {1, 1, 1}, ... {255, 255, 255}।

इस बिटमैप में एक एकल जीडीआई BitBlt आपकी मूल छवि को भूरे रंग में डाल देगा। यहां कोड स्निपेट है (सी ++, एटीएल और डब्ल्यूटीएल में - लेकिन आपको विचार मिलना चाहिए)।

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)); 
+0

क्या जीडीआई हेलफ़ोन पैलेट से आरक्षित सिस्टम रंगों को त्यागने की अनुमति देगा? – OnTheFly

+3

यह ग्रे के 256 रंगों के साथ पूरी तरह से ग्रेस्केल पैलेट बनाता है, कोई सिस्टम रंग नहीं। –

+0

@RomanR .: मुझे समझ में नहीं आता कि प्रारंभिक बिटमैप (जिसे परिवर्तित किया जाना है) यहां खेलता है। क्या आप कृपया स्पष्टीकरण दे सकते हैं? –

संबंधित मुद्दे