Autor Beitrag
CarpeDiem
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 128

WIN XP
Borland C++ 2002, CodeGear C++ 2007, C# (VS 2008)
BeitragVerfasst: Mi 02.04.08 13:25 
Hallo, ich programmiere zwar in C++(CodeGear), aber hier die Frage. Warum funktioniert mein folgender Quellcode nicht? Weiß jemand von Euch vielleicht die Antwort? Es ist zum Haare ausraufen.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  int *arrx_unten = new int[Screen->Width];
  int *arrx_oben = new int[Screen->Width];
  for (int y=0; y<Bitmap->Height; y++)
    {
    arrx_unten = Bitmap->ScanLine[y];
    arrx_oben = BitmapAlphablending->ScanLine[y];
    for (int x=0; x<Bitmap->Width; x++)
      {
      Bitmap->Canvas->Pixels[x][y] =
        (TColor)RGB(
          oben[(Alphawert << 8) + GetRValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetRValue(arrx_unten[x])],
          oben[(Alphawert << 8) + GetGValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetGValue(arrx_unten[x])],
          oben[(Alphawert << 8) + GetBValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetBValue(arrx_unten[x])]
          );
      }
    }
Danke gleich mal. In der markierten Zeile bekomme ich nach dem kompilieren eine Meldung "Konvertierung von void* nach int* nicht möglich. Wie kann ich es sonst noch realisieren?


Moderiert von user profile iconChristian S.: Topic aus Multimedia / Grafik verschoben am Mi 02.04.2008 um 16:21

_________________
Stefan - Carpe Diem
Es ist keine Schande zu fallen, eine Schande ist nur nicht wieder aufzustehen
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 02.04.08 15:47 
Du mußt entsprechend casten:
ausblenden Quelltext
1:
arrx_unten = static_cast<int *>(Bitmap->ScanLine[y]);					


Du mußt dir aber über das Bitmap-Format sicher sein. So wie du es jetzt programmiert hast, funktioniert es nur mit 32-Bit Werten (ARGB).

Du mußt erst das PixelFormat überprüfen und dann evtl. Byte für Byte auslesen (statt int).
CarpeDiem Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 128

WIN XP
Borland C++ 2002, CodeGear C++ 2007, C# (VS 2008)
BeitragVerfasst: Mi 02.04.08 16:00 
Danke, funktioniert. Aber warum brauche ich das da gerade? Das Format habe ich vorher schon folgendermaßen angepasst:
ausblenden C#-Quelltext
1:
Bitmap->PixelFormat = pf32bit;					

Warum werden dadurch aus ARGB jetzt BGRA?

_________________
Stefan - Carpe Diem
Es ist keine Schande zu fallen, eine Schande ist nur nicht wieder aufzustehen
CarpeDiem Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 128

WIN XP
Borland C++ 2002, CodeGear C++ 2007, C# (VS 2008)
BeitragVerfasst: Mi 02.04.08 16:16 
Wie kann man die Zeilen, die man mit
ausblenden C#-Quelltext
1:
arr = Bitmap->ScanLine[y]					

einliesst wieder schnell schreiben. Sowas wie
ausblenden C#-Quelltext
1:
Bitmap->WriteLine[y,arr]					

gibt es ja leider nicht. Bis jetzt mach ich es über
ausblenden C#-Quelltext
1:
Bitmap->Canvas->Pixels[x][y]					

_________________
Stefan - Carpe Diem
Es ist keine Schande zu fallen, eine Schande ist nur nicht wieder aufzustehen
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1340
Erhaltene Danke: 120

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mi 02.04.08 17:05 
Farbformat: Musst du testen, ich vergesse es immer wieder. Aber ich vermute ABGR.
Ich würde aber zum Zugriff statt Integer lieber Byte nehmen. Dafür dann halt Breite mal 4.
Dadurch kannst du dir die Funktionen für die Farbanteile sparen und lößt alles über Speicherzugriffe. (ist schneller)

Speichern:
ausblenden C#-Quelltext
1:
Bitmap->ScanLine[y] = arr					
erledigt.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
CarpeDiem Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 128

WIN XP
Borland C++ 2002, CodeGear C++ 2007, C# (VS 2008)
BeitragVerfasst: Mi 02.04.08 17:21 
Danke, aber der
ausblenden C#-Quelltext
1:
Bitmap->ScanLine[y] = arr					

funktioniert nicht, bringt immer die Fehlermeldung "Zugriff auf TBitmap::ScanLine nicht möglich".

_________________
Stefan - Carpe Diem
Es ist keine Schande zu fallen, eine Schande ist nur nicht wieder aufzustehen
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 04.04.08 08:17 
Die Scanlines ist eine nur lesen Eigenschaft des Bitmaps. Mehr muss aber auch nicht sein, denn Scanlines liefert dir den Pointer auf den Speicher des Bitmaps. Wenn du den Pointer dereferenzierst und etwas zuweist ist es auch schon im Bitmap.

Zum Zugriff. Byte / Integer? Wenn du einzelne Pixel setzen willst gibt es auch vorgefertigte Strukturen. Die heißen RGBQUAD und RGBTRIPLE. Entsprechend für 32 und 24 Bit Farbtiefe.

Th69: Ich glaube du verdrehst da was? Ein TColor oder COLORREF ist als 0x00BBGGRR abgespeichert. In einem 32 Bit Bitmap liegen die Daten im Format 0xBBGGRR00 vor.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
CarpeDiem Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 128

WIN XP
Borland C++ 2002, CodeGear C++ 2007, C# (VS 2008)
BeitragVerfasst: Fr 04.04.08 09:01 
Im Moment mache ich es halt so, der Compiler schluckt es auch, aber das Alphablending funktioniert nicht.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
  // Alphablending: Bitmaps übereinanderlegen
  TColor *arrx_unten = new TColor[Screen->Width];
  TColor *arrx_oben = new TColor[Screen->Width];
  for (int y=0; y<Bitmap->Height; y++)
    {
    arrx_unten = static_cast<TColor *>(Bitmap->ScanLine[y]);
    arrx_oben = static_cast<TColor *>(BitmapAlphablending->ScanLine[y]);
    for (int x=0; x<Bitmap->Width; x++)
      {
      BitmapPuffer->Canvas->Pixels[x][y] =
        (TColor)RGB(  // RGB ist hier BGR
          oben[(Alphawert << 8) + GetBValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetBValue(arrx_unten[x])],
          oben[(Alphawert << 8) + GetGValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetGValue(arrx_unten[x])],
          oben[(Alphawert << 8) + GetRValue(arrx_oben[x])] + unten[(Alphawert << 8) + GetRValue(arrx_unten[x])]
          );
      }
    }

Habe dann die markierte Zeile mit "arrx_unten =" ersetzt, funktioniert aber auch nicht.

_________________
Stefan - Carpe Diem
Es ist keine Schande zu fallen, eine Schande ist nur nicht wieder aufzustehen
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 04.04.08 12:38 
Also Pixels solltest du besser lassen, denn das geht immer über die Window API und das sind alles Funktionsaufrufe. Das ist einfach nur Langsam. Ich muss aber gestehen, dass ich nicht genau weiß was du schreiben musst. Und Code in Delphi wird dir sicher nicht viel helfen. Den gibt aber auch zu hauf im Delphi Forum.

Ich habe aber folgenden Code im Netz gefunden der das eigentlich verdeutlichen sollte.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  Byte *ptr;
  for (int y = 0; y < radio_grand->Picture->Bitmap->Height; y++)
  {
    ptr = (Byte *)radio_grand->Picture->Bitmap->ScanLine[y];

    for (int x = 0; x < 4*radio_grand->Picture->Bitmap->Width-2; x+=4)
    {
      ptr[x]=0xff;
      ptr[x+1]=0xcc;
      ptr[x+2]=0xaa;
    }
  }

Dort wird der Pointer aus Scanline genommen und ihm Daten zugewiesen. Du hast in der Deklarationen aber bereits einen Datenbereich erstellt und bei static_cast<TColor *> vermute ich einfach mal stark, dass du nicht nur den Pointer benutzt sondern ihn dereferenzierst und die Daten kopierst. Wobei ich bei TColor* sogar fast vermute, dass du nur ein einziges Pixel kopierst.

Zum Verrechnen des Alphas würde ich die Optimierungen erst mal weglassen und es funktional hinbekommen.
ausblenden Quelltext
1:
2:
3:
      ptrZiel[x]= ptrBild1[x] * Alpha + ptrBild2[x] * (1-Alpha);
      ptrZiel[x+1]= ptrBild1[x+1] * Alpha + ptrBild2[x+1] * (1-Alpha);
      ptrZiel[x+2]= ptrBild1[x+2] * Alpha + ptrBild2[x+2] * (1-Alpha);

Die ptr... Variablen sind nur pseudo. Also da musst du natürlich deine benutzen. Alpha ist dabei ein Floatwert im Bereich von 0-1. Die Konvertierung zwischen Float und Byte sollte der Compiler hoffentlich alleine hinbekommen. Kenne mich wie gesagt damit nicht wirklich gut aus. Deswegen möge man es mir verzeihen, wenn ich blödsinn laber.


PS: Ich weiß, dass ich codetags benutzt habe. Aber ich kenne die csharp tags nicht und meine JavaScript ist gerade etwas defekt. Also keine Chance es über die Buttons auszuwählen. ;)

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.