Skip to content

Instantly share code, notes, and snippets.

@robotconscience
Created September 10, 2014 16:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robotconscience/4718ae1ea6828278d9bf to your computer and use it in GitHub Desktop.
Save robotconscience/4718ae1ea6828278d9bf to your computer and use it in GitHub Desktop.
openFrameworks iOS image saving
//
// ofxiOSImageSaver.h
// Colorizer
//
// Created by Brett Renfer on 9/9/14.
//
#pragma once
#include "ofMain.h"
#import "AssetsLibrary/AssetsLibrary.h"
class ofxiOSImageEntry
{
public:
string url;
ofPixels pixels;
};
class ofxiOSImageArgs {
public:
string url;
int id;
};
class ofxiOSImageSaver : protected ofThread
{
public:
~ofxiOSImageSaver(){
waitForThread();
}
int saveImage( ofPixels & pix, string url = "" ){
static int _id = 0;
queue[_id].url = url;
queue[_id].pixels.setFromExternalPixels(pix.getPixels(), pix.getWidth(), pix.getHeight(), pix.getNumChannels());
queue[_id].pixels.setImageType(OF_IMAGE_COLOR_ALPHA); // iOS seems to only like RGBA?
if (!isThreadRunning()){
startThread();
}
_id++;
return _id;
};
ofEvent<ofxiOSImageArgs> onImageSaved;
protected:
void threadedFunction();
map<int, ofxiOSImageEntry> queue;
};
//
// ofxiOSImageSaver.cpp
// Colorizer
//
// Created by Brett Renfer on 9/9/14.
//
#include "ofxiOSImageSaver.h"
void ofxiOSImageSaver::threadedFunction()
{
if ( queue.size() > 0 ){
auto it = queue.begin();
int dispatchId = it->first;
ofPixels pix = it->second.pixels;
string url = it->second.url;
queue.erase(it);
int width = pix.getWidth();
int height = pix.getHeight();
int nChannels = pix.getNumChannels();
NSInteger myDataLength = width * height * nChannels;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pix.getPixels(), myDataLength, NULL);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGImageRef imageRef = CGImageCreate(width, height, 8, 32, nChannels * width, colorSpaceRef, kCGBitmapByteOrderDefault, provider, NULL, NO, kCGRenderingIntentDefault);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
UIImage * image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
NSData * imageData = UIImageJPEGRepresentation(image, 1.0);
// NSData * imageData = UIImagePNGRepresentation(image);
UIImage * imageLossless = [UIImage imageWithData:imageData];
static ofxiOSImageArgs args;
args.id = dispatchId;
// blank url = save to image library
if ( url == "" ){
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[imageLossless CGImage] orientation:(ALAssetOrientation)[imageLossless imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(@"error");
} else {
// NSLog(@"url %@", assetURL);
args.url = [[assetURL absoluteString] UTF8String];
ofNotifyEvent(onImageSaved, args, this);
}
}];
[library release];
} else {
NSFileManager *defaultManager = [NSFileManager defaultManager];
NSURL *docsURL = [[defaultManager URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSURL *outputURL = [docsURL URLByAppendingPathComponent:[NSString stringWithUTF8String:url.c_str()]];
[imageData writeToURL:outputURL atomically:YES];
args.url = [[outputURL absoluteString] UTF8String];
ofNotifyEvent(onImageSaved, args, this);
}
if ( queue.size() == 0){
stopThread();
}
}
}
@aferriss
Copy link

Hey there, does this still work? Images only seem to save if I leave the url blank, and even then they just show up black.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment