Qt: das PNG-Bild Transparenz verloren nach dem öffnen

Ich werde versuchen, öffnen Sie ein PNG-Bild mit QT, aber die alpha-Werte für die Pixel ist immer 255 auch wenn das Bild leer ist (D. H., der alpha-Wert sollte 0 sein)

Ich habe versucht, Konvertierung des Bildes in den ARGB-format nach dem laden aber das hat nicht geholfen. Hier ist ein Beispiel für eine leere png-ich versuche zu laden:

Bild:

enter image description here

QImage im = QImage("JGbVc0r.png");
int p1 = 20;
int p2 = 20;
QImage img = im.convertToFormat(QImage::Format_ARGB32);
qInfo()<<qRed(img.pixel(p1,p2))<<qBlue(img.pixel(p1,p2))<<qGreen(img.pixel(p1,p2))<<qAlpha(img.pixel(p1,p2));

Die erwartete Ausgabe ist 0 0 0 0 aber ich bekomme 255 255 255 255

Irgendwelche Vorschläge auf, wie die gewünschte Ausgabe erhalten? Vielen Dank im Voraus. Ich bin mit Qt 5.11.

1 Antworten

  • Scheff
    4. Mai 2019

    Ich habe versucht das Problem zu reproduzieren, OP.

    Leider imgur.com blockiert, in meiner Firma. Daher begann ich mit einem kleinen Beispiel-Bild, das ich vorbereitet in GIMP.

    Sample Image made in GIMP (8x8, RGBA) ← Es ist wirklich klein: 8x8 pixel mit RGBA-Kanälen.

    Als Nächstes machte ich eine kleine Beispielanwendung zum überprüfen des Ergebnisses in QImagetestQImageRGBA.cc:

    #include <iomanip>
    #include <iostream>
    
    #include <QtWidgets>
    
    void dump(
      const QImage &qImg, int row, int col,
      std::function<void(const QImage&, int, int)> dumpPixel)
    {
      qDebug() << qImg;
      const int nR = qImg.height(), nC = qImg.width();
      const int iR0 = row >= 0 ? row : 0;
      const int iRN = row >= 0 ? row + 1 : nR;
      const int iC0 = col >= 0 ? col : 0;
      const int iCN = col >= 0 ? col + 1 : nC;
      std::cout << "Dump of rows [" << iR0 << ", " << iRN << "),"
        << " cols [" << iC0 << ", " << iCN << ")\n"
        << "Pixel format: '#RRGGBBAA'\n";
      for (int iR = iR0; iR < iRN; ++iR) {
        for (int iC = iC0; iC < iCN; ++iC) {
          dumpPixel(qImg, iR, iC);
        }
        std::cout << '\n';
      }
    }
    
    int main(int argc, char **argv)
    {
      // pixel dump code like done by OP
      std::function<void(const QImage&, int, int)> dumpPixelOP // OPs flavor
        = [](const QImage &qImg, int iR, int iC) {
          std::cout << std::hex << "_#"
            << std::setw(2) << std::setfill('0') << qRed(qImg.pixel(iC, iR))
            << std::setw(2) << std::setfill('0') << qGreen(qImg.pixel(iC, iR))
            << std::setw(2) << std::setfill('0') << qBlue(qImg.pixel(iC, iR))
            << std::setw(2) << std::setfill('0') << qAlpha(qImg.pixel(iC, iR));
        };
      std::function<void(const QImage&, int, int)> dumpPixel // my flavor
        = [](const QImage &qImg, int iR, int iC) {
          const QColor pixel = qImg.pixelColor(iC, iR);
          std::cout << std::hex << " #"
            << std::setw(2) << std::setfill('0') << pixel.red()
            << std::setw(2) << std::setfill('0') << pixel.green()
            << std::setw(2) << std::setfill('0') << pixel.blue()
            << std::setw(2) << std::setfill('0') << pixel.alpha();
        };
      qDebug() << "Qt Version:" << QT_VERSION_STR;
      QApplication app(argc, argv);
      const QStringList args = app.arguments();
      const QString filePath = args.size() > 1 ? args[1] : "smiley.8x8.rgba.png";
      const int row = args.size() > 2 ? args[2].toInt() : -1;
      const int col = args.size() > 3 ? args[3].toInt() : -1;
      const bool useDumpOP = args.size() > 4;
      QImage qImg(filePath);
      qImg = qImg.convertToFormat(QImage::Format_ARGB32);
      dump(qImg, row, col, useDumpOP ? dumpPixelOP : dumpPixel);
      return 0;
    }
    

    und einer Qt-Projekt-Datei – testQImageRGBA.pro:

    SOURCES = testQImageRGBA.cc
    
    QT += widgets
    

    Kompiliert und getestet in cygwin64:

    $ qmake-qt5 testQImageRGBA.pro
    
    $ make && ./testQImageRGBA
    g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQImageRGBA.o testQImageRGBA.cc
    g++  -o testQImageRGBA.exe testQImageRGBA.o   -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 
    Qt Version: 5.9.4
    QImage(QSize(8, 8),format=5,depth=32,devicePixelRatio=1,bytesPerLine=32,byteCount=256)
    Dump of rows [0, 8), cols [0, 8)
    Pixel format: '#RRGGBBAA'
     #00000000 #00000000 #000000ff #000000ff #000000ff #000000ff #00000000 #00000000
     #00000000 #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff #00000000
     #000000ff #ffff00ff #0000ffff #ffff00ff #ffff00ff #0000ffff #ffff00ff #000000ff
     #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff
     #000000ff #ffff00ff #ff0000ff #ffff00ff #ffff00ff #ff0000ff #ffff00ff #000000ff
     #000000ff #ffff00ff #ffff00ff #ff0000ff #ff0000ff #ffff00ff #ffff00ff #000000ff
     #00000000 #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff #00000000
     #00000000 #00000000 #000000ff #000000ff #000000ff #000000ff #00000000 #00000000
    

    Der dump spiegelt genau das, was ich gezeichnet habe, in GIMP. Bitte beachten Sie die Pixel der Ecken, die sind schwarz, transparent.

    Ich bereitete ein CMake-source-Datei CMakeLists.txt:

    project(QImageRGBA)
    
    cmake_minimum_required(VERSION 3.10.0)
    
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)
    
    find_package(Qt5Widgets CONFIG REQUIRED)
    
    include_directories("${CMAKE_SOURCE_DIR}")
    
    add_executable(testQImageRGBA testQImageRGBA.cc)
    
    target_link_libraries(testQImageRGBA Qt5::Widgets)
    

    und kompiliert die gleiche Quelle in VS2017. Getestet in cmd.exe auf Windows 10:

    C:\Users\Scheff\tests\misc\Qt\QImageRGBA>set PATH=%PATH%;D:\Scheff\Qt\5.11.2\msvc2017_64\bin;$(LocalDebuggerEnvironment)
    
    C:\Users\Scheff\tests\misc\Qt\QImageRGBA>build-VS2017\Debug\testQImageRGBA.exe
    Qt Version: 5.11.2
    QImage(QSize(8, 8),format=5,depth=32,devicePixelRatio=1,bytesPerLine=32,sizeInBytes=256)
    Dump of rows [0, 8), cols [0, 8)
    Pixel format: '#RRGGBBAA'
     #00000000 #00000000 #000000ff #000000ff #000000ff #000000ff #00000000 #00000000
     #00000000 #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff #00000000
     #000000ff #ffff00ff #0000ffff #ffff00ff #ffff00ff #0000ffff #ffff00ff #000000ff
     #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff
     #000000ff #ffff00ff #ff0000ff #ffff00ff #ffff00ff #ff0000ff #ffff00ff #000000ff
     #000000ff #ffff00ff #ffff00ff #ff0000ff #ff0000ff #ffff00ff #ffff00ff #000000ff
     #00000000 #000000ff #ffff00ff #ffff00ff #ffff00ff #ffff00ff #000000ff #00000000
     #00000000 #00000000 #000000ff #000000ff #000000ff #000000ff #00000000 #00000000
    
    C:\Users\Scheff\tests\misc\Qt\QImageRGBA>
    

    Es gibt effektiv keinen Unterschied.


    Einmal zu Hause (mit Zugang zu imgur.com), die ich heruntergeladen habe das Bild von OP JGbVc0r.png und versuchte es erneut.

    Zuerst in cygwin64:

    $ make && ./testQImageRGBA JGbVc0r.png 20 20   
    make: Nothing to be done for 'first'.
    Qt Version: 5.9.4
    QImage(QSize(1000, 1000),format=5,depth=32,devicePixelRatio=1,bytesPerLine=4000,byteCount=4000000)
    Dump of rows [20, 21), cols [20, 21)
    Pixel format: '#RRGGBBAA'
     #00000000
    

    dann in VS2017 und cmd.exe:

    C:\Users\Scheff\tests\misc\Qt\QImageRGBA>build-VS2017\Debug\testQImageRGBA.exe
    Qt Version: 5.11.2
    QImage(QSize(1000, 1000),format=5,depth=32,devicePixelRatio=1,bytesPerLine=4000,sizeInBytes=4000000)
    Dump of rows [20, 21), cols [20, 21)
    Pixel format: '#RRGGBBAA'
     #00000000
    

    OP angegeben:

    Die erwartete Ausgabe ist 0 0 0 0

    und das ist genau das, was ich habe.


    vollgestopft bot einen interessanten Hinweis auf eine Falle über QColor::QColor(QRgb) was ist Gegenstand der F/A

    ALSO: QImage Einstellung alpha-PNG mit Transparenz.

    Allerdings kam ich zu dem Schluss, dass dies sollte nicht das Problem sein, weil hier in der OPs-code

    qInfo()<<qRed(img.pixel(p1,p2))<<qBlue(img.pixel(p1,p2))<<qGreen(img.pixel(p1,p2))<<qAlpha(img.pixel(p1,p2));
    

    Daher die underhanding QColor::QColor(QRgb) ist einfach nicht beteiligt. Zur Beseitigung meiner letzten Zweifel, ich wollte einfach nur diese auch in cygwin:

    $ make && ./testQImageRGBA JGbVc0r.png 20 20 dumpLikeOP  
    make: Nothing to be done for 'first'.
    Qt Version: 5.9.4
    QImage(QSize(1000, 1000),format=5,depth=32,devicePixelRatio=1,bytesPerLine=4000,byteCount=4000000)
    Dump of rows [20, 21), cols [20, 21)
    Pixel format: '#RRGGBBAA'
    _#00000000
    

    und in VS2017 und cmd.exe:

    C:\Users\Scheff\tests\misc\Qt\QImageRGBA>build-VS2017\Debug\testQImageRGBA.exe
    Qt Version: 5.11.2
    QImage(QSize(1000, 1000),format=5,depth=32,devicePixelRatio=1,bytesPerLine=4000,sizeInBytes=4000000)
    Dump of rows [20, 21), cols [20, 21)
    Pixel format: '#RRGGBBAA'
    _#00000000
    

    Also, ich kann einfach nicht reproduzieren Sie das Problem des OP, obwohl ich mich sehr bemühte.

    Die OP dauert vielleicht meinen code zu testen, wie gut. Entweder OP übersehen, der etwas anderes war nicht offen in Frage, oder es gibt ein bestimmtes Problem auf OP ' s system.