Autor |
Beitrag |
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Sa 02.11.02 17:55
Hilfe,
wie kann ich ein Bitmap in Graustufen konvertieren? Egal wie,
hauptsache ohne auf die Festplatte zu speichern... (Vom virtuellen Speicher mal abgesehen)
maxk
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
OregonGhost
      
Beiträge: 215
|
Verfasst: 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)
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Sa 02.11.02 20:13
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
OregonGhost
      
Beiträge: 215
|
Verfasst: 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.
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)
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Tomac
      
Beiträge: 113
Win XP
D6 Ent
|
Verfasst: 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 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: 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
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: 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 
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Tomac
      
Beiträge: 113
Win XP
D6 Ent
|
Verfasst: Mo 11.11.02 15:00
Der Code von mir müsste funktionieren.
Woran scheiterts?
|
|
Tomac
      
Beiträge: 113
Win XP
D6 Ent
|
Verfasst: Mo 11.11.02 15:02
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Sa 16.11.02 12:54
04.02.2003 - Bilder entfernt
Ich habe den oben genannten Code benutzt.
Quelle: Borland Delphi Splash Screens
maxk
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Zuletzt bearbeitet von maxk am Di 04.02.03 11:54, insgesamt 1-mal bearbeitet
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: 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
      
Beiträge: 215
|
Verfasst: 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.
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: 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
maxk
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
|