Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Save QImage from BYTE buffer segfaults ?
Forum Update on Monday, May 27th 2025

Save QImage from BYTE buffer segfaults ?

Scheduled Pinned Locked Moved Solved General and Desktop
qimagebmpbytes
43 Posts 8 Posters 11.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • hskoglundH Offline
    hskoglundH Offline
    hskoglund
    wrote on last edited by hskoglund
    #33

    Hi, you could try explicitly specify the number of bytes per line:
    Edit: also, it could be that your deleting the buffer before the QImage is deleted:

    BYTE *buf = new BYTE(imWidth * imHeight);
    //Populate buf with data using API call here (not shown)
    {
        QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
        img.save("image.bmp", "BMP");
    }
    delete [] buf;
    
    R 1 Reply Last reply
    0
    • hskoglundH hskoglund

      Hi, you could try explicitly specify the number of bytes per line:
      Edit: also, it could be that your deleting the buffer before the QImage is deleted:

      BYTE *buf = new BYTE(imWidth * imHeight);
      //Populate buf with data using API call here (not shown)
      {
          QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
          img.save("image.bmp", "BMP");
      }
      delete [] buf;
      
      R Offline
      R Offline
      R-P-H
      wrote on last edited by
      #34

      @hskoglund said in Save QImage from BYTE buffer segfaults ?:

      Hi, you could try explicitly specify the number of bytes per line:
      Edit: also, it could be that your deleting the buffer before the QImage is deleted:

      BYTE *buf = new BYTE(imWidth * imHeight);
      //Populate buf with data using API call here (not shown)
      {
          QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
          img.save("image.bmp", "BMP");
      }
      delete [] buf;
      

      Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

      I also tried with removing the delete [] buf line and still the same.

      B 1 Reply Last reply
      0
      • R R-P-H

        @hskoglund said in Save QImage from BYTE buffer segfaults ?:

        Hi, you could try explicitly specify the number of bytes per line:
        Edit: also, it could be that your deleting the buffer before the QImage is deleted:

        BYTE *buf = new BYTE(imWidth * imHeight);
        //Populate buf with data using API call here (not shown)
        {
            QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
            img.save("image.bmp", "BMP");
        }
        delete [] buf;
        

        Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

        I also tried with removing the delete [] buf line and still the same.

        B Offline
        B Offline
        Bonnie
        wrote on last edited by
        #35

        @R-P-H
        If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
        As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
        So I won't be surprised that it crashes.

        R 1 Reply Last reply
        0
        • B Bonnie

          @R-P-H
          If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
          As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
          So I won't be surprised that it crashes.

          R Offline
          R Offline
          R-P-H
          wrote on last edited by
          #36

          @Bonnie said in Save QImage from BYTE buffer segfaults ?:

          @R-P-H
          If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
          As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
          So I won't be surprised that it crashes.

          I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

          B 1 Reply Last reply
          0
          • R R-P-H

            @Bonnie said in Save QImage from BYTE buffer segfaults ?:

            @R-P-H
            If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
            As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
            So I won't be surprised that it crashes.

            I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

            B Offline
            B Offline
            Bonnie
            wrote on last edited by Bonnie
            #37

            @R-P-H
            Right, this is another problem.
            How can you be sure your populated data is not all black?
            I will suggest you do some tests without Qt classes.

            BYTE *buf = new BYTE[imWidth * imHeight];
            //Populate buf with data using API call here (not shown)
            bool AllZero = true;
            for(int i = 0; i < imWidth * imHeight; i++) {
                if(buf[i] != 0)
                    AllZero = false;
            }
            qDebug() << "AllZero :" << AllZero;
            delete [] buf;
            

            Or you can just print all of the data to see whether it is all zero(black).

            R 1 Reply Last reply
            0
            • B Bonnie

              @R-P-H
              Right, this is another problem.
              How can you be sure your populated data is not all black?
              I will suggest you do some tests without Qt classes.

              BYTE *buf = new BYTE[imWidth * imHeight];
              //Populate buf with data using API call here (not shown)
              bool AllZero = true;
              for(int i = 0; i < imWidth * imHeight; i++) {
                  if(buf[i] != 0)
                      AllZero = false;
              }
              qDebug() << "AllZero :" << AllZero;
              delete [] buf;
              

              Or you can just print all of the data to see whether it is all zero(black).

              R Offline
              R Offline
              R-P-H
              wrote on last edited by R-P-H
              #38

              @Bonnie said in Save QImage from BYTE buffer segfaults ?:

              @R-P-H
              Right, this is another problem.
              How can you be sure your populated data is not all black?
              I will suggest you do some tests without Qt classes.

              BYTE *buf = new BYTE[imWidth * imHeight];
              //Populate buf with data using API call here (not shown)
              bool AllZero = true;
              for(int i = 0; i < imWidth * imHeight; i++) {
                  if(buf[i] != 0)
                      AllZero = false;
              }
              qDebug() << "AllZero :" << AllZero;
              delete [] buf;
              

              Or you can just print all of the data to see whether it is all zero(black).

              Yes it's all black everytime.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                R-P-H
                wrote on last edited by
                #39

                I would like to try save the buffer to a
                BMP image using only standard C++ just to check that it's not a problem with using QImage. But I haven't been able to get that working yet...

                1 Reply Last reply
                0
                • hskoglundH Offline
                  hskoglundH Offline
                  hskoglund
                  wrote on last edited by
                  #40

                  QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                  int imWidth = 260;
                  int imHeight = 300;
                  
                  typedef unsigned char BYTE;
                  BYTE *buf = new BYTE[imWidth * imHeight];
                  
                  for (int y = 0; (y < imHeight); ++y)
                      for (int x = 0; (x < imWidth); ++x)
                          buf[x + y * imWidth] = x*x + y*y;
                  
                  QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                  
                  img.save("image.bmp", "BMP");
                  delete [] buf;
                  

                  I get:
                  Screenshot 2020-07-10 at 01.49.14.png

                  R 1 Reply Last reply
                  1
                  • hskoglundH Offline
                    hskoglundH Offline
                    hskoglund
                    wrote on last edited by
                    #41

                    Hi again, dug around in my old projects (turn-of-the-century old :-) and I found this function to write grey BMP files the hard way:

                    void save_bitmap_grey8(char* file_name, int width, int height, BYTE* pixel_data)
                    {
                        #pragma pack(push, 1)
                        struct bitmap_file_header
                        {
                            short bitmap_type;
                            int   file_size;
                            short reserved1;
                            short reserved2;
                            int   offset_bits;
                        } bfh;
                        #pragma pack(pop)
                    
                        struct bitmap_image_header
                        {
                            int   size_header;
                            int   width;
                            int   height;
                            short planes;
                            short bit_count;
                            int   compression;
                            int   image_size;
                            int   ppm_x;
                            int   ppm_y;
                            int   clr_used;
                            int   clr_important;
                        } bih;
                    
                        struct grey_palette { BYTE r; BYTE g; BYTE b; BYTE a; } gp[256];
                        for (int i = 0; (i < 256); ++i)
                        {
                             gp[i].r = gp[i].g = gp[i].b = i;
                             gp[i].a = 0;
                        }
                    
                        int imagesize = height * (((width * 8 + 31) & ~31) / 8);
                    
                        memcpy(&bfh.bitmap_type, "BM", 2);
                        bfh.file_size   = sizeof(bfh) + sizeof(bih) + sizeof(gp) + imagesize;
                        bfh.reserved1   = 0;
                        bfh.reserved2   = 0;
                        bfh.offset_bits = sizeof(bfh) + sizeof(bih) + sizeof(gp);
                    
                        bih.size_header   = sizeof(bih);
                        bih.width         = width;
                        bih.height        = height;
                        bih.planes        = 1;
                        bih.bit_count     = 8;
                        bih.compression   = 0;
                        bih.image_size    = imagesize;
                        bih.ppm_x         = 3780; // meter->inch->96 ppi
                        bih.ppm_y         = 3780; // same here
                        bih.clr_used      = 256;
                        bih.clr_important = 256;
                    
                        FILE* image = fopen(file_name, "wb");
                        fwrite(&bfh, 1, sizeof(bfh), image);
                        fwrite(&bih, 1, sizeof(bih), image);
                        fwrite(&gp, 1, sizeof(gp), image);
                        fwrite(pixel_data, 1, width * height, image);
                    
                        fclose(image);
                    }
                    

                    So just swap out QImage with the above function, like this:

                    int imWidth = 260;
                    int imHeight = 300;
                    
                    BYTE *buf = new BYTE[imWidth * imHeight];
                    
                    for (int y = 0; (y < imHeight); ++y)
                        for (int x = 0; (x < imWidth); ++x)
                            buf[x + y * imWidth] = x*x + y*y;
                    
                    save_bitmap_grey8("image.bmp",imWidth,imHeight,buf);
                    
                    delete [] buf;
                    

                    Looks exactly the same, except....
                    Screenshot 2020-07-10 at 05.35.30.png it's upside down! That's a relic of OS/2's spec. for bitmaps, they wanted (x =0 , y = 0) to be in lower left corner instead of top left corner. QImage fixes this but my code has that vintage upside/down bug :-)

                    1 Reply Last reply
                    1
                    • hskoglundH hskoglund

                      QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                      int imWidth = 260;
                      int imHeight = 300;
                      
                      typedef unsigned char BYTE;
                      BYTE *buf = new BYTE[imWidth * imHeight];
                      
                      for (int y = 0; (y < imHeight); ++y)
                          for (int x = 0; (x < imWidth); ++x)
                              buf[x + y * imWidth] = x*x + y*y;
                      
                      QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                      
                      img.save("image.bmp", "BMP");
                      delete [] buf;
                      

                      I get:
                      Screenshot 2020-07-10 at 01.49.14.png

                      R Offline
                      R Offline
                      R-P-H
                      wrote on last edited by
                      #42

                      @hskoglund Thanks for the info ! Looks to me like the API is not populating the buffer hence why it is all black.

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        R-P-H
                        wrote on last edited by
                        #43

                        @mranger90 said in Save QImage from BYTE buffer segfaults ?:

                        try:
                        BYTE *buf = new BYTE[imWidth * imHeight];

                        So the issue turned out to be with the device itself. Changing the code as above and replacing the device solved the issue. Thanks.

                        1 Reply Last reply
                        1

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved