Entwickler-Ecke
Multimedia / Grafik - Bitmap in Graustufen umwandeln
maxk - Sa 02.11.02 17:55
Titel: Bitmap in Graustufen umwandeln
Hilfe,
wie kann ich ein Bitmap in Graustufen konvertieren? Egal wie,
hauptsache ohne auf die Festplatte zu speichern... (Vom virtuellen Speicher mal abgesehen)
maxk
OregonGhost - Sa 02.11.02 18:36
Eine Möglichkeit ist, mit CreateBitmap oder CreateDIBSection eine Graustufen-Bitmap zu erstellen von derselben Größe wie die Quellbitmap, und dann einfach mit BitBlt die Quellbitmap auf die neue Bitmap zu blitten. Windows übernimmt dann glaub ich das Farbmanagement automatisch, naja, jedenfalls sieht das Graustufenergebnis ganz gut aus ;c)
maxk - Sa 02.11.02 20:13
:?: :?: :?: Kannst du mit da mal ein Beispiel coden?
OregonGhost - So 03.11.02 17:29
Nein, aber ich gebe dir den Quellcode aus einem meiner Programme. Ich habe das Problem wie folgt gelöst, da ich schnellen Zugriff auf die Pixeldaten brauchte. Vielleicht ist das für dein Programm etwas überdimensioniert, aber es wird funktionieren. Ist in C geschrieben, wenn du damit nicht klarkommst, kann ich dir noch beim Übersetzen helfen.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| BYTE* g_GrayBits = NULL;
// Quellbitmap laden und Größe abfragen HBITMAP g_hSource = (HBITMAP) LoadImage(NULL, szFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); BITMAP bm; GetObject(g_hSource, sizeof(BITMAP), &bm);
// Graustufenbitmap erzeugen BITMAPINFO * bmi = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = bm.bmWidth; bmi->bmiHeader.biHeight = bm.bmHeight; bmi->bmiHeader.biPlanes = 1; bmi->bmiHeader.biBitCount = 8; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biSizeImage = 0; bmi->bmiHeader.biXPelsPerMeter = 72000; bmi->bmiHeader.biYPelsPerMeter = 72000; bmi->bmiHeader.biClrUsed = 0; bmi->bmiHeader.biClrImportant = 0; for (int i = 0; i < 256; i++) { bmi->bmiColors[i].rgbRed = i; bmi->bmiColors[i].rgbGreen = i; bmi->bmiColors[i].rgbBlue = i; bmi->bmiColors[i].rgbReserved = 0; } HBITMAP g_hGrayscale = CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, (void**)&g_GrayBits, NULL, 0);
// Quellbitmap auf Graustufenbitmap kopieren HDC cdc = GetDC(NULL), dcs = CreateCompatibleDC(cdc), dct = CreateCompatibleDC(cdc); ReleaseDC(NULL, cdc); HBITMAP hbmOlds = (HBITMAP)SelectObject(dcs, g_hSource); HBITMAP hbmOldt = (HBITMAP)SelectObject(dct, g_hGrayscale); BitBlt(dct, 0, 0, bm.bmWidth, bm.bmHeight, dcs, 0, 0, SRCCOPY); SelectObject(dcs, hbmOlds); SelectObject(dct, hbmOldt); DeleteDC(dct); DeleteDC(dcs);
// Naja, hier könntest du die Quellbitmap mit DeleteObject(g_hSource); // freigeben. |
Achtung, g_hGrayscale ist hier ein lokaler Handle, vielleicht solltest du eine Funktion schreiben die ihn zurückliefert. In meinem Programm ist g_hGrayscale global, auch wenn das nicht wirklich schicklich ist ;c)
Ich weiß nicht genau, wie man CreateBitmap() oder CreateCompatibleBitmap() zu diesem Zwecke verwenden kann, das wäre um einiges kürzer als CreateDIBSection() ;c)
Tomac - So 03.11.02 20:05
Titel: hier in Delphi
Und hier mal das Ganze in Delphi- Code:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure TForm1.RGBtoGray; type Pixelarray = array[1..3] of Byte; var PPixels: ^Pixelarray; i,u: Integer; Newcolor: Byte begin with image1.picture.bitmap do begin for i:= 0 to height-1 do begin PPixels := Scanline[i]; for u:=0 to width-1 do begin Newcolor:= HiByte (PPixels^[1]*76 +PPixels^[2]*149 +PPixels^[3]*28); PPixels^[1]:=Newcolor; PPixels^[2]:=Newcolor; PPixels^[3]:=Newcolor; inc(PPixels); end; end; end; image1.refresh; end; |
sollte funktionieren
mfG
Tomac
maxk - Di 05.11.02 18:22
Yoh,so viel Code - und so wenig Zeit...
Aber erstmal Danke für die schnellen Antworten, ich werd's probieren.
maxk
maxk - So 10.11.02 21:32
Sorry, der Code klappt bei mir nicht. Habs mit den Splashbildern von Borland ausprobiert.
Was kann ich noch tun :?:
Tomac - Mo 11.11.02 15:00
Der Code von mir müsste funktionieren.
Woran scheiterts?
Tomac - Mo 11.11.02 15:02
edit: Sorry, Doppelpost.
maxk - Sa 16.11.02 12:54
04.02.2003 - Bilder entfernt
Ich habe den oben genannten Code benutzt.
Quelle: Borland Delphi Splash Screens
maxk
Aya - Sa 16.11.02 19:58
Hi,
hier die funktion die ich in meinem GrafikProg dafür benutze:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function Grayscale(Bitmap: TBitmap; Rect: TRect): Boolean; var x, y: Integer; P: PByteArray; res: Byte; begin for y:=Rect.Top to Rect.Bottom-1 do begin P:=Bitmap.ScanLine[y]; for x:=Rect.Left to Rect.Right-1 do begin res:=Round((P^[x*3]+P^[x*3+1]+P^[x*3+2])/3); P^[x*3]:=res; P^[x*3+1]:=res; P^[x*3+2]:=res; end; end; Result:=True; end; |
Bitmap ist einfach das Bitmap das in Graufstufen umgewandelt werden soll.
Rect ist der Teil vom Bitmap der in Graufstufen umgewandelt werden soll.
Aufruf wenn das gesammte Bitmap grau sein soll:
Quelltext
1:
| function Grayscale(Image1.Picture.Bitmap,Rect(0,0,Image1.Picture.Bitmap.Width,Image1.Picture.Bitmap.Height)): |
Au'revoir,
Aya[/b]
OregonGhost - So 17.11.02 17:49
Die beiden zuletzt genannten Codes funktionieren nur, wenn die Quellgrafik RGB, um genau zu sein R8G8B8 ist. Die Borland Splash Screens haben 16 bzw. 256 Farben. Der Code, den ich oben gepostet habe, funktioniert mit allen Farbtiefen.
maxk - Sa 12.04.03 15:49
Nagut, ums abzuschließen:
1. BMP nach JPEG konvertieren
2. JPEG in Stream speichern
3. JPEG aus Stream laden
4. JPEG nach BMP konvertieren
Nach etwa 3 Stunden steht der Rechner nach Aufruf wieder zur Verfügung :wink:
maxk
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!