[SOLVED] How to store a qimage to iOS Camera Roll (Photo Album) ?
-
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,
-
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.
-
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
-
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; }
-
@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 postBest,
Marek -
-
Good question... You should contact the Qt Company directly for a clear answer.