Autor Beitrag
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Sa 02.11.02 20:13 
:?: :?: :?: Kannst du mit da mal ein Beispiel coden?

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
OregonGhost
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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.
ausblenden volle Höhe 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)

_________________
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
Tomac
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 113

Win XP
D6 Ent
BeitragVerfasst: So 03.11.02 20:05 
Titel: hier in Delphi
Und hier mal das Ganze in Delphi- Code:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 113

Win XP
D6 Ent
BeitragVerfasst: Mo 11.11.02 15:00 
Der Code von mir müsste funktionieren.
Woran scheiterts?
Tomac
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 113

Win XP
D6 Ent
BeitragVerfasst: Mo 11.11.02 15:02 
edit: Sorry, Doppelpost.
maxk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Sa 16.11.02 19:58 
Hi,

hier die funktion die ich in meinem GrafikProg dafür benutze:

ausblenden 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:
ausblenden Quelltext
1:
function Grayscale(Image1.Picture.Bitmap,Rect(0,0,Image1.Picture.Bitmap.Width,Image1.Picture.Bitmap.Height)):					


Au'revoir,
Aya[/b]
OregonGhost
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.