Hello,
Can anyone give me the formula to transfrom color images to grey image ?
Thanks :(
29.9 % red
58,7 % green
11.4 % blue
= 100% grey
The formula that I have, from Programmer's Guide to the EGA and VGA Cards by Richard F. Ferraro, is:
Gray Scale = (.30 * red) + (.59 * green) + (.11 * blue)
I have seen some variations, but I think this is the one that was developed originally by IBM, and implemented in the VGA BIOS for the SumToGrayScale function.
The grays displayed by this test app don't look right to me, but the numbers seem to check out.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
Paint_Proc PROTO :DWORD,:DWORD
FRGB MACRO red, green, blue
xor eax, eax
mov ah, blue ; blue
mov al, green ; green
rol eax, 8
mov al, red ; red
EXITM <eax>
ENDM
GRAY MACRO red, green, blue
LOCAL rval
.data
rval dd 0
align 4
.code
fld8 <red>.0
fld8 0.30
fmul
fld8 <green>.0
fld8 0.59
fmul
fld8 <blue>.0
fld8 0.11
fmul
fadd
fadd
fistp rval
mov eax, rval
rol eax, 8
or eax, rval
rol eax, 8
or eax, rval
EXITM <eax>
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInst dd 0
hWnd dd 0
wc WNDCLASSEX <>
msg MSG <>
className db "gray_scale_test"
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
MsgBox 0,uhex$(GRAY(255,0,0)),"R",0
MsgBox 0,uhex$(GRAY(0,255,0)),"G",0
MsgBox 0,uhex$(GRAY(0,0,255)),"B",0
mov hInst, rv(GetModuleHandle, NULL)
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET className
mov wc.hIcon, NULL
mov wc.hCursor, NULL
mov wc.hIconSm, 0
invoke RegisterClassEx, ADDR wc
invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW,
ADDR className,
chr$("Test"),
WS_OVERLAPPEDWINDOW,
0,0,600,400,
NULL, NULL,
hInst, NULL
mov hWnd, eax
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd
msgLoop:
invoke GetMessage, ADDR msg, NULL, 0, 0
.IF (eax != 0)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp msgLoop
.ENDIF
exit msg.wParam
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WndProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
LOCAL hDC :DWORD
LOCAL ps :PAINTSTRUCT
.IF (uMsg == WM_DESTROY)
invoke PostQuitMessage, NULL
return 0
.ELSEIF (uMsg == WM_PAINT)
invoke BeginPaint, hWin, ADDR ps
mov hDC, eax
invoke Paint_Proc, hWin, hDC
invoke EndPaint, hWin, ADDR ps
return 0
.ENDIF
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Paint_Proc proc hWin:DWORD, hDC:DWORD
invoke GetStockObject, DC_PEN
invoke SelectObject, hDC, eax
invoke GetStockObject, DC_BRUSH
invoke SelectObject, hDC, eax
invoke SetDCPenColor, hDC, FRGB(255,0,0)
invoke SetDCBrushColor, hDC, FRGB(255,0,0)
invoke Rectangle, hDC, 20, 20, 120, 120
invoke SetDCPenColor, hDC, GRAY(255,0,0)
invoke SetDCBrushColor, hDC, GRAY(255,0,0)
invoke Rectangle, hDC, 130, 20, 230, 120
invoke SetDCPenColor, hDC, FRGB(0,255,0)
invoke SetDCBrushColor, hDC, FRGB(0,255,0)
invoke Rectangle,hDC, 20, 130, 120, 230
invoke SetDCPenColor, hDC, GRAY(0,255,0)
invoke SetDCBrushColor, hDC, GRAY(0,255,0)
invoke Rectangle, hDC, 130, 130, 230, 230
invoke SetDCPenColor, hDC, FRGB(0,0,255)
invoke SetDCBrushColor, hDC, FRGB(0,0,255)
invoke Rectangle,hDC, 20, 240, 120, 340
invoke SetDCPenColor, hDC, GRAY(0,0,255)
invoke SetDCBrushColor, hDC, GRAY(0,0,255)
invoke Rectangle, hDC, 130, 240, 230, 340
ret
Paint_Proc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Thank You !
This is really what I need.
Here is what I have done with it :
mov DWord Ptr [_dCent],100
fild DWord Ptr [_dCent]
fst QWord Ptr [_dCent]
fild DWord Ptr [dwGrey_Red]
fdiv QWord Ptr [_dCent]
fst QWord Ptr [_dRed]
fild DWord Ptr [dwGrey_Green]
fdiv QWord Ptr [_dCent]
fst QWord Ptr [_dGreen]
fild DWord Ptr [dwGrey_Blue]
fdiv QWord Ptr [_dCent]
fst QWord Ptr [_dBlue]
mov ebx,DWord Ptr [lpImageBits]
mov edx,DWord Ptr [lpWork]
mov edi,DWord Ptr [Image.bmHeight]
GreyScale_Work_Loop :
mov esi,DWord Ptr [Image.bmWidth]
GreyScale_Work_Loop_1 :
mov eax,DWord Ptr [ebx]
and eax,0ffh
mov DWord Ptr [_dwBlue],eax
mov eax,DWord Ptr [ebx]
shr eax,8
and eax,0ffh
mov DWord Ptr [_dwGreen],eax
mov eax,DWord Ptr [ebx]
shr eax,16
mov DWord Ptr [_dwRed],eax
fild DWord Ptr [_dwRed]
fld QWord Ptr [_dRed]
fmul
fld DWord Ptr [_dwGreen]
fild DWord Ptr [_dGreen]
fmul
fld DWord Ptr [_dwBlue]
fild DWord Ptr [_dBlue]
fmul
fadd
fadd
fistp DWord Ptr [_dVal]
mov eax,DWord Ptr [_dVal]
rol eax,8
or eax,DWord Ptr [_dVal]
rol eax,8
or eax,DWord Ptr [_dVal]
mov DWord Ptr [edx],eax
GreyScale_Work_Loop_2 :
add ebx,SIZEOF DWord
add edx,SIZEOF DWord
I have found that good values also are Red=70%, Green=70% and Blue=5%.
In this case the sum of Red, Green and Blue is greather than 100% ! But this not not an error. Images are lighter than with the previous formula. If you want to limit the sum to 100%, you have to do :
factor = 1 / (Red+Green+blue)
and apply this factor to each color.
If you have others ideas or formulas for grayscale and image working send them to me.
The attachment is supposed to be a visual test to determine if the grayscale results for the coefficients 0.30, 0.59, and 0.11 reasonably mimic the luminosity for the corresponding primary color. The general idea here is to create primary and grayscale gradients that fade to black at the same rate. If the gradients have the same luminosity, then the primary and corresponding grayscale gradients should fade into the black background at about the same horizontal position. For my display (a Sony Trinitron), the red and green grayscales are OK, but the blue grayscale seems generally darker than the blue primary, and the grayscale gradient fades into the black background a little (perhaps 40 pixels) before the blue gradient does. The coefficients 0.29, 0.53, and 0.18 seem to work OK.
[attachment deleted by admin]
The values you give do darks images. The lighter values are 70,70 and 10. I tooke them from "The Gimp". "Photoshop" has the possibility to desaturate, this give grey image leaving white areas unchanged and black areas become grey. I don't know how it does. But this the best result... this "Photoshop" too.
Where can I find formulas about effets to give an image ?
I have found some effects in assembly language, they all are written by BitRAKE and seems good. I have not tested them again.
I would like to convert part of a color image into grey part, and others effects without using the last parameter of "StretchBlt". In my program I have the original image bits into a buffer, this buffer is modified by effects and then put on the window. The image size on the window is different that the original. When the program save a result it saves a memory buffer not the window image.
Thank you for every one who helps me.
The problems I see with 70-70-10 are that the luminosity would increase, and the conversion would not differentiate between reds and greens.
http://www.gimp.org/tutorials/Color2BW/
I used the same doc...
for r, g, b
(r*ctl(0)+g*ctl(1)+b*ctl(2))/(ctl(0)+ctl(1)+ctl(2))
ctl() range 1 to ? (0 to 255 in the example FF plugin: Grey.8bf - dividing by 0 works in Filter Factory for some reason)
this file is a plugin for Photoshop or PSP or ...
www.bmath.net/dc/download/ind/DC_GreyScaler4.8bf
Desaturate in GIMP:
Note on the first page for the Grayscale function: "The formula used in the GIMP is Y = 0.3R + 0.59G + 0.11B; this result is known as luminance".
http://gimp-savvy.com/BOOK/node54.html
http://www.informit.com/articles/article.asp?p=131019&seqNum=4&rl=1
Donkey has some Graphics Code/Library, including a fast grayscales routine here:
http://donkey.visualassembler.com/
I know a lot of his code is in GoAsm. So some conversion maybe needed.
Regards, P1 :8)
I took a look at Donkey's code and it is interesting to note that he is using essentually the same values as Michael.
Quote
25 => 11.36% Blue
129 => 58.63% Green
66 => 30.00% Red
---------------------------------
220 => 99.99% Gray
Take it for what it is worth...
Paul
Thanks to everyone :boohoo:,
Now I have a lot to do.
All these informations will me in my "Images Effects" programs.