Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pour ceux qui connaissent gdi+, j'ai vraiment besoin d'aide

5 réponses
Avatar
Loïc
Salut tout le monde. J'ai un très gros souci avec un projet que je
développe. Je cherche depuis deux semaine sans aucun résultat positif.

J'ai besoin de convertir une image bmp 24 bits en niveau de gris. J'ai
une fonction qui me fait très bien ça sauf que... Ca me génère une
image avec une palette de couleur de 32 bits!!! Je suis complètement
perdu. J'aimerai donc pouvoir générer une bitmap avec un format de
pixel codé sur 8bits.

J'ai exactement le même problème avec une fonction qui me génère du
noir et blanc... je me retrouve avec une image bmp 32 bits...

Si quelqu'un pouvait m'aider ne serait ce qu'un peu. Je galère vraiment
trop là.

Merci d'avance.

Loïc

PS: voici ma fonction de convertion d'image en niveau de gris:

je passe le handle de ma bitmap 24 bits en paramètre. (image créée avec
gdpcreateBitmapFromFile)
la fonction me retourne un handle vers une nouvelle image niveau de
gris (mais c'est de la palette 32bpp :( )...




Public Function SetGreyScale(nNativeImage as long) As Long


Dim nGraphics As Long
Dim nNewBmp As Long
Dim nHeight As Long
Dim nWidth As Long
Dim imgAttr As Long, clrMatrix As ColorMatrix
Dim sngContrast As Single


sngContrast = 0.35
nHeight = GetHeight
nWidth = GetWidth


clrMatrix.m(0, 0) = sngContrast: clrMatrix.m(1, 0) = sngContrast:
clrMatrix.m(2, 0) = sngContrast: clrMatrix.m(3, 0) = 0: clrMatrix.m(4,
0) = 0
clrMatrix.m(0, 1) = sngContrast: clrMatrix.m(1, 1) = sngContrast:
clrMatrix.m(2, 1) = sngContrast: clrMatrix.m(3, 1) = 0: clrMatrix.m(4,
1) = 0
clrMatrix.m(0, 2) = sngContrast: clrMatrix.m(1, 2) = sngContrast:
clrMatrix.m(2, 2) = sngContrast: clrMatrix.m(3, 2) = 0: clrMatrix.m(4,
2) = 0
clrMatrix.m(0, 3) = 0: clrMatrix.m(1, 3) = 0: clrMatrix.m(2, 3) =
0: clrMatrix.m(3, 3) = 1: clrMatrix.m(4, 3) = 0
clrMatrix.m(0, 4) = 0: clrMatrix.m(1, 4) = 0: clrMatrix.m(2, 4) =
0: clrMatrix.m(3, 4) = 0: clrMatrix.m(4, 4) = 1


Call GdipCreateImageAttributes(imgAttr)
Call GdipSetImageAttributesColorMatrix(imgAttr,
ColorAdjustTypeDefault, True, clrMatrix, ByVal 0,
ColorMatrixFlagsDefault)


Call GdipGetImageGraphicsContext(nNativeImage, nGraphics)
Call GdipCreateBitmapFromGraphics(nWidth, nHeight, nGraphics,
nNewBmp)
Call GdipDeleteGraphics(nGraphics) ' Cleanup so we can reuse
the variable
Call GdipGetImageGraphicsContext(nNewBmp, nGraphics)
Call GdipDrawImageRectRectI(nGraphics, nNativeImage, 0, 0, nWidth,
nHeight, 0, 0, nWidth, nHeight, UnitPixel, imgAttr)
Call GdipDisposeImageAttributes(imgAttr)
GdipDisposeImage nNativeImage
nNativeImage = nNewBmp
GdipDeleteGraphics nGraphics
Call GdipDisposeImage(nNativeImage)

SetGreyScale = nNewBmp
End Function

--
Loïc

5 réponses

Avatar
ng
Salut,

Je ne suis pas un spécialiste du GDI+, je poste simplement ci-dessous une
fonction que j'utilise (qui n'est pas de moi) qui permet de sauvegarder un
picturebox en un BMP N&B (c'est du GDI classique) :


Private Const LR_CREATEDIBSECTION = &H2000
Private Const LR_DEFAULTCOLOR = &H0
Private Const LR_DEFAULTSIZE = &H40
Private Const LR_LOADFROMFILE = &H10
Private Const LR_LOADMAP3DCOLORS = &H1000
Private Const LR_LOADTRANSPARENT = &H20
Private Const LR_MONOCHROME = &H1
Private Const LR_SHARED = &H8000
Private Const LR_COPYFROMRESOURCE = &H4000
Private Const BI_RGB = 0&
Private Const BI_RLE8 = 1&
Private Const BI_RLE4 = 2&
Private Const BI_BITFIELDS = 3&
Private Const DIB_RGB_COLORS = 0
Private Const SRCCOPY = &HCC0020
Private Const IMAGE_BITMAP = 0
Private Const LR_COPYRETURNORG = &H4
Private Const CF_BITMAP = 2
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type tagRGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors(1) As tagRGBQUAD
End Type
Private Type BITMAP '14 bytes
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type BITMAPFILEHEADER
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal
hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal
un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long)
As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal
hObject As Long) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal
hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits
As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As
Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long

Public Function SaveMonoBmp(picSrce As PictureBox, ByVal SaveFileName As
String) As Boolean

Dim bmap As BITMAP, bmapinfo_1 As BITMAPINFO
Dim bmapfileheader As BITMAPFILEHEADER
Dim SaveBytes() As Byte
Dim filenum As Integer
Dim newhand As Long, hMemDC As Long
Dim oldhand As Long
Dim BytesPerScanline As Long, imagesize As Long

Dim lRet As Long

GetObject picSrce.Image, Len(bmap), bmap

newhand = CopyImage(picSrce.Image, IMAGE_BITMAP, _
bmap.bmWidth, bmap.bmHeight, LR_MONOCHROME)

hMemDC = CreateCompatibleDC(0)
oldhand = SelectObject(hMemDC, newhand)

With bmapinfo_1.bmiHeader
.biSize = 40
.biWidth = bmap.bmWidth
.biHeight = bmap.bmHeight
.biPlanes = 1
.biBitCount = 1 'bmap.bmBitsPixel
.biCompression = BI_RGB
BytesPerScanline = ((((.biWidth * .biBitCount) + 31) 32) * 4)
imagesize = BytesPerScanline * .biHeight
.biSizeImage = imagesize
End With

ReDim SaveBytes(1 To imagesize)
lRet = GetDIBits(hMemDC, newhand, _
0, bmapinfo_1.bmiHeader.biHeight, _
SaveBytes(1), _
bmapinfo_1, _
DIB_RGB_COLORS)

With bmapfileheader
.bfType = &H4D42
.bfOffBits = Len(bmapfileheader) + Len(bmapinfo_1)
.bfSize = .bfOffBits + imagesize
End With

'Save to file
On Error GoTo errHandler
filenum = FreeFile
Open SaveFileName For Binary As filenum
Put filenum, , bmapfileheader
Put filenum, , bmapinfo_1
Put filenum, , SaveBytes()
Close filenum

'Clean Up
SelectObject hMemDC, oldhand
DeleteObject newhand
DeleteDC hMemDC

''if you get here all went well
SaveMonoBmp = True
Exit Function

errHandler:
MsgBox Err.Description

End Function

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Loïc wrote:
Salut tout le monde. J'ai un très gros souci avec un projet que je
développe. Je cherche depuis deux semaine sans aucun résultat positif.

J'ai besoin de convertir une image bmp 24 bits en niveau de gris. J'ai
une fonction qui me fait très bien ça sauf que... Ca me génère une
image avec une palette de couleur de 32 bits!!! Je suis complètement
perdu. J'aimerai donc pouvoir générer une bitmap avec un format de
pixel codé sur 8bits.

J'ai exactement le même problème avec une fonction qui me génère du
noir et blanc... je me retrouve avec une image bmp 32 bits...

Si quelqu'un pouvait m'aider ne serait ce qu'un peu. Je galère
vraiment trop là.

Merci d'avance.

Loïc

PS: voici ma fonction de convertion d'image en niveau de gris:

je passe le handle de ma bitmap 24 bits en paramètre. (image créée
avec gdpcreateBitmapFromFile)
la fonction me retourne un handle vers une nouvelle image niveau de
gris (mais c'est de la palette 32bpp :( )...




Public Function SetGreyScale(nNativeImage as long) As Long


Dim nGraphics As Long
Dim nNewBmp As Long
Dim nHeight As Long
Dim nWidth As Long
Dim imgAttr As Long, clrMatrix As ColorMatrix
Dim sngContrast As Single


sngContrast = 0.35
nHeight = GetHeight
nWidth = GetWidth


clrMatrix.m(0, 0) = sngContrast: clrMatrix.m(1, 0) = sngContrast:
clrMatrix.m(2, 0) = sngContrast: clrMatrix.m(3, 0) = 0: clrMatrix.m(4,
0) = 0
clrMatrix.m(0, 1) = sngContrast: clrMatrix.m(1, 1) = sngContrast:
clrMatrix.m(2, 1) = sngContrast: clrMatrix.m(3, 1) = 0: clrMatrix.m(4,
1) = 0
clrMatrix.m(0, 2) = sngContrast: clrMatrix.m(1, 2) = sngContrast:
clrMatrix.m(2, 2) = sngContrast: clrMatrix.m(3, 2) = 0: clrMatrix.m(4,
2) = 0
clrMatrix.m(0, 3) = 0: clrMatrix.m(1, 3) = 0: clrMatrix.m(2, 3) > 0: clrMatrix.m(3, 3) = 1: clrMatrix.m(4, 3) = 0
clrMatrix.m(0, 4) = 0: clrMatrix.m(1, 4) = 0: clrMatrix.m(2, 4) > 0: clrMatrix.m(3, 4) = 0: clrMatrix.m(4, 4) = 1


Call GdipCreateImageAttributes(imgAttr)
Call GdipSetImageAttributesColorMatrix(imgAttr,
ColorAdjustTypeDefault, True, clrMatrix, ByVal 0,
ColorMatrixFlagsDefault)


Call GdipGetImageGraphicsContext(nNativeImage, nGraphics)
Call GdipCreateBitmapFromGraphics(nWidth, nHeight, nGraphics,
nNewBmp)
Call GdipDeleteGraphics(nGraphics) ' Cleanup so we can reuse
the variable
Call GdipGetImageGraphicsContext(nNewBmp, nGraphics)
Call GdipDrawImageRectRectI(nGraphics, nNativeImage, 0, 0, nWidth,
nHeight, 0, 0, nWidth, nHeight, UnitPixel, imgAttr)
Call GdipDisposeImageAttributes(imgAttr)
GdipDisposeImage nNativeImage
nNativeImage = nNewBmp
GdipDeleteGraphics nGraphics
Call GdipDisposeImage(nNativeImage)

SetGreyScale = nNewBmp
End Function


Avatar
Loïc
Merci, c'est sympa mais il me faut le faire avec gdi+ car j'effectue
d'autre traitement sur l'image avec ce dernier. J'utilisais gdi32
auparavant pour faire ce traitement mais je ne pouvais pas transférer
une image de gdi32 à gdi+ sans avoir systématiquement la palette de
couleur à 32bpp... Je me retrouve avec le même problème avec cette
solution.

Merci encore

Loïc

--
Loïc
Avatar
ng
Salut,

Donc désolé je ne connais pas gdi+, il te faudra attendre d'autre réponse ou
peut être essayer de consulter les archives.

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Loïc wrote:
Merci, c'est sympa mais il me faut le faire avec gdi+ car j'effectue
d'autre traitement sur l'image avec ce dernier. J'utilisais gdi32
auparavant pour faire ce traitement mais je ne pouvais pas transférer
une image de gdi32 à gdi+ sans avoir systématiquement la palette de
couleur à 32bpp... Je me retrouve avec le même problème avec cette
solution.

Merci encore

Loïc


Avatar
christophe-pasde
Salut,

GDI+ je connais pas encore, tu dis que tu récupère une image en palette
de couleur, au niveau du codage des pixels c'est idem ?
Quatre octets par pixel ?

Pourrais-tu indiquer l'objet colormatrix, c'est à toi ou c'est du GDI+
standard ?

Peut-être pourras-tu trouver une réponse en anglais sur
microsoft.public.vb.winapi.graphics

Tu as l'air de créer une image par
Call GdipSetImageAttributesColorMatrix(imgAttr, ColorAdjustTypeDefault,
True, clrMatrix, ByVal 0, ColorMatrixFlagsDefault)

Quelle est la valeur de colorajusttypedefault c'est pas couleur 32 bits?

Je pense pas que la GDIplus change fondamentalement la gestion des
bitmap ça doiu continuer de ce faire au travers de DIB mais la table de
couleurs est absente et c'est caler sur la palette de couleur, ceci par
défaut, à toi si tu veux passer en 1 octet par pixel de préparer le
bitmap en conséquence, enfin à mon humble avis.

Christophe




Loïc a écrit :

Merci, c'est sympa mais il me faut le faire avec gdi+ car j'effectue
d'autre traitement sur l'image avec ce dernier. J'utilisais gdi32
auparavant pour faire ce traitement mais je ne pouvais pas transférer
une image de gdi32 à gdi+ sans avoir systématiquement la palette de
couleur à 32bpp... Je me retrouve avec le même problème avec cette
solution.

Merci encore

Loïc



Avatar
christophe-pasde
Sois patient,
pour la réponse au post sur winapigraphic, la personne qui à mon avis
peut te répondre semble être absente ces quelques jours.

Christophe

Loïc a écrit :
Salut tout le monde. J'ai un très gros souci avec un projet que je
développe. Je cherche depuis deux semaine sans aucun résultat positif.

J'ai besoin de convertir une image bmp 24 bits en niveau de gris. J'ai
une fonction qui me fait très bien ça sauf que... Ca me génère une image
avec une palette de couleur de 32 bits!!! Je suis complètement perdu.
J'aimerai donc pouvoir générer une bitmap avec un format de pixel codé
sur 8bits.

J'ai exactement le même problème avec une fonction qui me génère du noir
et blanc... je me retrouve avec une image bmp 32 bits...

Si quelqu'un pouvait m'aider ne serait ce qu'un peu. Je galère vraiment
trop là.

Merci d'avance.

Loïc

PS: voici ma fonction de convertion d'image en niveau de gris:

je passe le handle de ma bitmap 24 bits en paramètre. (image créée avec
gdpcreateBitmapFromFile)
la fonction me retourne un handle vers une nouvelle image niveau de gris
(mais c'est de la palette 32bpp :( )...




Public Function SetGreyScale(nNativeImage as long) As Long


Dim nGraphics As Long
Dim nNewBmp As Long
Dim nHeight As Long
Dim nWidth As Long
Dim imgAttr As Long, clrMatrix As ColorMatrix
Dim sngContrast As Single


sngContrast = 0.35
nHeight = GetHeight
nWidth = GetWidth


clrMatrix.m(0, 0) = sngContrast: clrMatrix.m(1, 0) = sngContrast:
clrMatrix.m(2, 0) = sngContrast: clrMatrix.m(3, 0) = 0: clrMatrix.m(4,
0) = 0
clrMatrix.m(0, 1) = sngContrast: clrMatrix.m(1, 1) = sngContrast:
clrMatrix.m(2, 1) = sngContrast: clrMatrix.m(3, 1) = 0: clrMatrix.m(4,
1) = 0
clrMatrix.m(0, 2) = sngContrast: clrMatrix.m(1, 2) = sngContrast:
clrMatrix.m(2, 2) = sngContrast: clrMatrix.m(3, 2) = 0: clrMatrix.m(4,
2) = 0
clrMatrix.m(0, 3) = 0: clrMatrix.m(1, 3) = 0: clrMatrix.m(2, 3) = 0:
clrMatrix.m(3, 3) = 1: clrMatrix.m(4, 3) = 0
clrMatrix.m(0, 4) = 0: clrMatrix.m(1, 4) = 0: clrMatrix.m(2, 4) = 0:
clrMatrix.m(3, 4) = 0: clrMatrix.m(4, 4) = 1


Call GdipCreateImageAttributes(imgAttr)
Call GdipSetImageAttributesColorMatrix(imgAttr,
ColorAdjustTypeDefault, True, clrMatrix, ByVal 0, ColorMatrixFlagsDefault)


Call GdipGetImageGraphicsContext(nNativeImage, nGraphics)
Call GdipCreateBitmapFromGraphics(nWidth, nHeight, nGraphics, nNewBmp)
Call GdipDeleteGraphics(nGraphics) ' Cleanup so we can reuse the
variable
Call GdipGetImageGraphicsContext(nNewBmp, nGraphics)
Call GdipDrawImageRectRectI(nGraphics, nNativeImage, 0, 0, nWidth,
nHeight, 0, 0, nWidth, nHeight, UnitPixel, imgAttr)
Call GdipDisposeImageAttributes(imgAttr)
GdipDisposeImage nNativeImage
nNativeImage = nNewBmp
GdipDeleteGraphics nGraphics
Call GdipDisposeImage(nNativeImage)

SetGreyScale = nNewBmp
End Function