Conversion may lose significant digits



  • "Nur" eine Warnung, aber unsignifikanten Code sollte man noch verbessern können:

    void __fastcall TPixi::HellerClick(TObject *Sender)
    {
        int i,j;
        unsigned char *ptr;
        try
        {
            for (i=0;i < Image->Picture->Bitmap->Height;i++)
            {
                unsigned char *aptr = (byte*)Image->Picture->Bitmap->ScanLine[i];
                for (j=0;j < Image->Picture->Bitmap->Width*3;j++)
                {
                    ptr  = aptr + j;
                    // nach *ptr =| [C++Warnung] PixMain.cpp(382):
                    //          Conversion may lose significant digits.
                    *ptr = (*ptr+12>255 ? 255 : *ptr+12);
                }
            }
        }
        catch (...)
        {};
        Image->Refresh();
    }
    

    Klar hab ich verschiedene Schreibweisen probiert. "Probiert" bedeutet aber, daß ich mich nicht wirklich auskenn. Weiß jemand die Lösung?



  • Wieso willst Du prüfen, ob ein Byte einen Wert größer 255 enthalten soll? Das gibt es gar nicht. Da passt maximal 255 rein....?

    Außerdem habe ich noch nie gesehen, daß man bei einem Zugriff auf den Speicher solche "Spirenzchen" macht.

    Ich vermute, Dein Problem liegt darin, daß der Compiler den Ausdruck 12>255 logisch auswertet und immer zum binären Ergebnis 00000000000000000000000000000000 kommt. Das sind dann nämlich 32 Bit und die passen bekanntlich nicht in ein Byte rein...

    Schreib also *ptr = *(ptr+12); und gut is...



  • Ich will doch nichts überprüfen sondern das Bild heller machen. Der Code ist aus einem Antwortpost, ich hab ihn definitiv nicht verstanden. Ich weiß nicht, was diese Manöver sollen. Weiß nur, es funktioniert. 🙄

    Dein Code verschiebt das Bild nach links, der abgeschnittene Teil wird rechts wieder drangesetzt. Das nützt also nichts.

    Wie müßte denn die Syntax richtig aussehen, um das Bild heller zu machen?



  • Hi Omega-X

    Die Warnung kann mit nem TypeCast zu (byte) verhindert werden!

    !! Du hast einen Pointer auf BYTE!!!

    Dein Programm kann komplett abschmieren!!!

    for (j=0;j < Image->Picture->Bitmap->Width*3;j++)

    laeuft 3x soweit, wie Scanline lang ist! Das geht nur gut, wenn Farbtiefe 3Byte ist (24 Bit). Bei 'ner 8Bit Grafik haut das Ding hinten durch! (Exception)



  • Eeeendlich kapier ich, was ...*3 bedeutet. Hab das auch in einem anderen Beispiel (dort sogar *4), aber PixelFormat war dort explizit auf pf32bit gesetzt worden.

    Jo, dann muß ich hier erst mal je pf fallweise arbeiten, sonst knallt mit das Ding wirklich mal um die Ohren. 😮

    Bleibt nur noch die Arbeitszeile. Ich kann sie zwar umbauen und Typecast mit reinnehmen, aber ich bekomm immer andere Ergebnisse. Die Bildhelligkeit wird nicht beeinflußt. - Wieder eine von den ganz simplen Lösungen, die ich nur nicht seh? 🙄



  • du solltest statt mit BYTE mit RGBTRIPLE bzw. RGBQUAD arbeiten, dass ist wesentlich einfacher wie ich finde. dann kannst du die einzelnen farbwerte direkt ansprechen.

    beispiel:

    //---------------------------------------------------------------------------
    // funktion mach aus einen RGB-bild ein Graustufen-Bild
    //---------------------------------------------------------------------------
    void __fastcall TForm1::RGBToGray(Graphics::TBitmap *bmp)
    {
      Graphics::TBitmap *bmp_gray = new Graphics::TBitmap();
    
      bmp_gray->Assign(bmp);
    
      // über die höhe
      for (int j = 0; j < bmp_gray->Height; j++)
      {
        // eine zeile des bildes einlesen
        RGBTRIPLE *SL = (RGBTRIPLE *) bmp_gray->ScanLine[j];
    
        // über die breite
        for (int i = 0; i < bmp_gray->Width; i++)
        {
          BYTE gray;
    
          // bild normal ausgrauen oder mit helligkeitsanpassung 
          // (ist für menschliches auge besser erkennbar)
          if (CheckBox3->Checked)
            gray = (SL[i].rgbtRed * 0.299) + (SL[i].rgbtGreen * 0.587) + (SL[i].rgbtBlue * 0.114);
          else
            gray = (SL[i].rgbtRed + SL[i].rgbtGreen + SL[i].rgbtBlue) / 3;
    
          // farbwerte wieder zuweisen
          SL[i].rgbtRed   = gray;
          SL[i].rgbtGreen = gray;
          SL[i].rgbtBlue  = gray;
        }
      }
    
      // bild auf formular anzeigen
      Image1->Picture->Bitmap->Width  = bmp_gray->Width;
      Image1->Picture->Bitmap->Height = bmp_gray->Height;
      Image1->Picture->Bitmap         = bmp_gray;
    
      delete bmp_gray;
    }
    


  • Wahnsinnig interessant, @Sunday. Graustufen hatte ich mir für später aufgespart. Un nu?... 😃 + *Superdank* 🕶 Logo hab ich damit 'ne Weile gespielt. :p

    Ole, die Hilfe sagt, ich veränder die Farbkanäle relativ zueinander. Aber muß deswegen jede Operation unausweichlich grau oder Schwarz ergeben?

    else if (Sender == Neutralverdacht)
                    gray = (SL[i].rgbtRed*1) + (SL[i].rgbtGreen*1) +
                            (SL[i].rgbtBlue*1);
    

    Bringt kunterbunten Grau-Kauderwelsch.

    Manche Rechenwege haben sogar Chaosähnliche Strukturen. Bleibt man lange genug auf der Tastakombi, erscheint wieder die erste Abfolge, scheinbar beliebig oft wiederholbar. Nur das Original kommt nie mehr.

    Wo sind meine Farben? Ich weiß genau, daß sie da waren. :p Regel ich einen Kanal hoch und halt die anderen flach, sollte doch eine Gamma-Korrektur draus derden. Addier ich zu allen einen bestimmten Wert, sollte das Bild heller werden, aber die Farben behalten.

    Und... [C++Warnung] PixMain.cpp(1375): Conversion may lose significant digits.

    Die Warnung kommt für gray = .

    Mit Pointern und (byte) arbeiten, hat eher echte Fehler gebracht statt Besserung. Ist die Warnung unvermeidlich oder rührt eventuell daher, daß niemals Farben erhalten bleiben?

    Wer kann Dunkelheit ins Licht der Freude bringen? :p


Anmelden zum Antworten