Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. [SOLVED] How to store a qimage to iOS Camera Roll (Photo Album) ?

[SOLVED] How to store a qimage to iOS Camera Roll (Photo Album) ?

Scheduled Pinned Locked Moved Mobile and Embedded
11 Posts 5 Posters 5.7k 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.
  • A Offline
    A Offline
    aqmah
    wrote on 6 May 2014, 13:58 last edited by
    #1

    Hi, i am trying to port an native Objective C iOS App to an QT App.
    The App uses the iPhone/iPad Camera and should create an Image which is saved to the Camera Roll of the Device.

    So here is the Problem: How do I access the Camera Roll or what Path (QStandardPaths::PicturesLocation returns an empty string) I need to use when saving an Image.

    Thanks,

    1 Reply Last reply
    0
    • A Offline
      A Offline
      aqmah
      wrote on 12 May 2014, 10:41 last edited by
      #2

      Ok it seems no one ever tried this or ever succeeded.

      I found only a dirty way to do it without going too deep in UIImage and QtImage Logic - I didn't have the time so I needed to use already working Algorithm.

      For my "solution" you need the OpenCV Framework in your Qt Project (see my post http://qt-project.org/forums/viewthread/41530/ how to do this). Basically you have to Convert the QImage to an IplImage and then the IplImage to an UIImage.

      To accomplish that you need to use following code in a Qt/Objective C Hybrid mm File (see http://el-tramo.be/blog/mixing-cocoa-and-qt/ for how to mix Objective C and C++ in Qt) :

      @
      #include "cv.h"

      #import <Foundation/NSData.h>
      #import <UIKit/UIKit.h>

      UIImage* GetUIImg(IplImage* iplImage) {
      // NOTE Do not try to include this function in your header, because it will
      // need UIImage and if you add the UIKit Objective C Lib in your header
      // to make the Type visible the Qt Preprocessor will try to Process the
      // UIKit Lib as C++ and will fail
      cv::Mat cvMat = cv::cvarrToMat(iplImage);

      NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
      
      CGColorSpaceRef colorSpace;
      
      if (cvMat.elemSize() == 1)
      {
          colorSpace = CGColorSpaceCreateDeviceGray();
      }
      else
      {
          colorSpace = CGColorSpaceCreateDeviceRGB();
      }
      
      CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
      
      CGImageRef imageRef = CGImageCreate(cvMat.cols,                                     // Width
                                          cvMat.rows,                                     // Height
                                          8,                                              // Bits per component
                                          8 * cvMat.elemSize(),                           // Bits per pixel
                                          cvMat.step[0],                                  // Bytes per row
                                          colorSpace,                                     // Colorspace
                                          kCGImageAlphaNone | kCGBitmapByteOrderDefault,  // Bitmap info flags
                                          provider,                                       // CGDataProviderRef
                                          NULL,                                           // Decode
                                          false,                                          // Should interpolate
                                          kCGRenderingIntentDefault);                     // Intent
      
      UIImage* imgResult = [[UIImage alloc] initWithCGImage:imageRef];
      
      CGImageRelease(imageRef);
      CGDataProviderRelease(provider);
      CGColorSpaceRelease(colorSpace);
      
      cvMat.release();
      
      return imgResult;
      

      }

      void ObjCHelpers::saveImgToGallery(QImage qimg4Album) {
      QImage* qImage = &qimg4Album;

      int width = qImage->width();
      int height = qImage->height();
      CvSize Size;
      Size.height = height;
      Size.width = width;
      
      IplImage *ipl4Album = cvCreateImage(Size, IPL_DEPTH_8U, 1);
      char *charTemp = (char *) ipl4Album->imageData;
      
      for (int y = 0; y < height; y++)
      {
          for (int x = 0; x < width; x++)
          {
              int index = y * width + x;
              charTemp[index] = (char) qGray(qImage->pixel(x, y));
          }
      }
      
      UIImage* uiimg4Album = GetUIImg(ipl4Album);
      
      UIImageWriteToSavedPhotosAlbum(uiimg4Album, Nil, Nil, Nil);
      

      }
      @

      Its not a perfect solution but it works for me. If someone knows how an QImage is stored internally and knows the same about an UIImage, he could do the Convertion without using an IplImage but I already use the OpenCV Framework in my Project and had an working Ipl to UI Image Convertion in another Project so it was the simplest way for me.

      1 Reply Last reply
      1
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 12 May 2014, 21:24 last edited by
        #3

        Hi,

        QImage can be of several "formats":http://qt-project.org/doc/qt-5/qimage.html#image-formats and "here":http://qt-project.org/doc/qt-5/qimage.html#Format-enum

        You should also take a look at QtMacExtras, you have a helper function to get a CGImageRef from a QPixmap.

        Hope it helps

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Charby
          wrote on 9 Jan 2016, 22:04 last edited by
          #4

          Sorry to dig this old topic.
          I also needed to save a picture to the camera roll, and I thought that such a frequent use case would be supported "out of the box" by Qt, unfortunately after almost a complete day of browsing the web I haven't found a ready to use and working solution.
          I liked aqmah solution but I didn't want to add OpenCV dependency to my project just for this.

          Unfortunately QtMacExtras is no longer available on iOS.
          I have thus modified aqmah solution to come up with an acceptable solution without OpenCV.

          I know it is far from perfect but still it could be of some help :

          bool saveImgToGallery(const QImage& qimg4Album) {
              UIImage* uiimg4Album = QImage2UIImmage(qimg4Album);
              if ( uiimg4Album){
                  UIImageWriteToSavedPhotosAlbum( uiimg4Album, Nil, Nil, Nil);
                  return true;
              }
              return false;
          }
          
          UIImage* QImage2UIImmage(const QImage& img)
          {
              if (img.isNull()) return nullptr;
              CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, img.bits(), img.byteCount(), nullptr);
              CGColorSpaceRef colorSpace = img.isGrayscale() ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
              
          CGImageRef imageRef = CGImageCreate( 
                  img.width(),  img.height(), 
                  8, img.depth(), img.bytesPerLine(), 
                  colorSpace, getFlagsFromImageFormat(img.format()),
                  provider, NULL, false, kCGRenderingIntentDefault);
              
              CGImageRelease(imageRef);
              CGDataProviderRelease(provider);
              CGColorSpaceRelease(colorSpace);
          
              return imgResult;
          }
          
          uint getFlagsFromImageFormat(QImage::Format frm)
          {
              uint cgFlags = kCGImageAlphaNone;
              switch (frm) {
              case QImage::Format_ARGB32:
                  cgFlags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
                  break;
              case QImage::Format_RGB32:
                  cgFlags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
                  break;
              case QImage::Format_RGB888:
                  cgFlags = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
                  break;
              case QImage::Format_RGBA8888_Premultiplied:
                  cgFlags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
                  break;
              case QImage::Format_RGBA8888:
                  cgFlags = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
                  break;
              case QImage::Format_RGBX8888:
                  cgFlags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
                  break;
              case QImage::Format_ARGB32_Premultiplied:
                  cgFlags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
                  break;
              default:
                  cgFlags = kCGImageAlphaNone;
              }
              return cgFlags;
          }
          
          M 1 Reply Last reply 7 Mar 2020, 10:54
          1
          • G Offline
            G Offline
            GBergamo
            wrote on 16 Sept 2016, 16:02 last edited by
            #5

            Hi, and what if I need to download an image and save it in the camera roll?
            I'm using Qt 5.5.1, pictures location seems to be correct and when saving I don't get any error but I can't find the image on the gallery app!

            1 Reply Last reply
            0
            • C Charby
              9 Jan 2016, 22:04

              Sorry to dig this old topic.
              I also needed to save a picture to the camera roll, and I thought that such a frequent use case would be supported "out of the box" by Qt, unfortunately after almost a complete day of browsing the web I haven't found a ready to use and working solution.
              I liked aqmah solution but I didn't want to add OpenCV dependency to my project just for this.

              Unfortunately QtMacExtras is no longer available on iOS.
              I have thus modified aqmah solution to come up with an acceptable solution without OpenCV.

              I know it is far from perfect but still it could be of some help :

              bool saveImgToGallery(const QImage& qimg4Album) {
                  UIImage* uiimg4Album = QImage2UIImmage(qimg4Album);
                  if ( uiimg4Album){
                      UIImageWriteToSavedPhotosAlbum( uiimg4Album, Nil, Nil, Nil);
                      return true;
                  }
                  return false;
              }
              
              UIImage* QImage2UIImmage(const QImage& img)
              {
                  if (img.isNull()) return nullptr;
                  CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, img.bits(), img.byteCount(), nullptr);
                  CGColorSpaceRef colorSpace = img.isGrayscale() ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
                  
              CGImageRef imageRef = CGImageCreate( 
                      img.width(),  img.height(), 
                      8, img.depth(), img.bytesPerLine(), 
                      colorSpace, getFlagsFromImageFormat(img.format()),
                      provider, NULL, false, kCGRenderingIntentDefault);
                  
                  CGImageRelease(imageRef);
                  CGDataProviderRelease(provider);
                  CGColorSpaceRelease(colorSpace);
              
                  return imgResult;
              }
              
              uint getFlagsFromImageFormat(QImage::Format frm)
              {
                  uint cgFlags = kCGImageAlphaNone;
                  switch (frm) {
                  case QImage::Format_ARGB32:
                      cgFlags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
                      break;
                  case QImage::Format_RGB32:
                      cgFlags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
                      break;
                  case QImage::Format_RGB888:
                      cgFlags = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
                      break;
                  case QImage::Format_RGBA8888_Premultiplied:
                      cgFlags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
                      break;
                  case QImage::Format_RGBA8888:
                      cgFlags = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
                      break;
                  case QImage::Format_RGBX8888:
                      cgFlags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
                      break;
                  case QImage::Format_ARGB32_Premultiplied:
                      cgFlags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
                      break;
                  default:
                      cgFlags = kCGImageAlphaNone;
                  }
                  return cgFlags;
              }
              
              M Offline
              M Offline
              Marek
              wrote on 7 Mar 2020, 10:54 last edited by
              #6

              @Charby Hi
              I know this is old topic but maybe you could help ?
              I'm trying to save image to iOS gallery using your code, in QImage2UIImmage function there is missing conversion from CGImageRef to UIImage.
              I have created my class based on your example, but application is crashing each time when I want to save photo.
              I have described crash and provided code in this post

              Best,
              Marek

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Charby
                wrote on 7 Mar 2020, 11:10 last edited by Charby 3 Jul 2020, 11:10
                #7

                Hi Marek,
                Sorry I don't see anything obvious from your so post...
                Actually I no longer do mobile development with Qt on iOS since QtC ramped down the Indie licensing program.
                I hope you will find shortly a nice and easy fix.
                Best regards.
                Charby

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 7 Mar 2020, 21:40 last edited by
                  #8

                  @Charby Did you saw the new offering ? Might be an option again.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Charby
                    wrote on 7 Mar 2020, 23:53 last edited by
                    #9

                    Yes, I heard about its announcement but I don't think it is effective yet (?). I might consider it (even if it is more expensive than indie plan used to be) if one can be confident it won't be dropped without prior notice...

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 8 Mar 2020, 00:10 last edited by
                      #10

                      Good question... You should contact the Qt Company directly for a clear answer.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      C 1 Reply Last reply 8 Mar 2020, 00:13
                      0
                      • S SGaist
                        8 Mar 2020, 00:10

                        Good question... You should contact the Qt Company directly for a clear answer.

                        C Offline
                        C Offline
                        Charby
                        wrote on 8 Mar 2020, 00:13 last edited by
                        #11

                        @SGaist I will as soon as the new offering will be available. Thanks

                        1 Reply Last reply
                        0

                        • Login

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