CGImageSourceCreateImageAtIndex returns nil - ios

I'm trying to convert a pdf file to an image with this solution :
CFURLRef urlRef = (CFURLRef)[NSURL fileURLWithPath:#"http://uat.okitoo.fr/document/document/s595_506cb1811852f/o_specimen-page-seule.pdf"];
CGImageSourceRef src = CGImageSourceCreateWithURL(urlRef, NULL);
NSDictionary* options = [NSDictionary dictionaryWithObject:(id)[NSNumber numberWithInt:500] forKey:(id)kCGImageSourceThumbnailMaxPixelSize];
CGImageRef firstPage = CGImageSourceCreateImageAtIndex(src, 0, (CFDictionaryRef)options);
UIImage* imagePDF = [UIImage imageWithCGImage:firstPage];
CGImageRelease(firstPage);
My pdf file is ok but when I try this code, the image doesn't appear and I have this message : ": ImageIO: CGImageSourceCreateImageAtIndex image source parameter is nil". I can't understand..
I tried with other links but I have the same problem..
Any ideas ?
Is there an other way to convert my pdf file to an image ?
Thanks a lot !

You are using the incorrect API to create the URL, you need URLWithString:
CFURLRef urlRef = (CFURLRef)[NSURL URLWithString:#"http://uat.okitoo.fr/document/document/s595_506cb1811852f/o_specimen-page-seule.pdf"];
The API you are currently using is for urls to files on your local file system.

As the message says, your urlRef is probably nil.
Probably because you didn't mention the real full path but only the file name, and it can't find the file.
If your PDF is a file inside your application bundle, use [[NSBundle mainBundle] pathForResource:#"test" ofType:#"pdf"]. If you downloaded it at runtime to some place in your sandbox, simply use the path to where the PDF has been downloaded.

Related

raw CIFilter has nil outputImage

I get some DNG raw files and want to show them in iPhone. I use CIFilter to read the raw file, but when I try to get the outputImage, it returns nil.
The code looks like:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"1" withExtension:#"DNG"];
CIFilter *filter = nil;
filter = [CIFilter filterWithImageURL:url options:nil];
[filter setValue:#(2000) forKey:kCIInputNeutralTemperatureKey];
CIImage *imgCI = [filter.outputImage imageByApplyingFilter:#"CIVignette"];//5
UIImage *img = [UIImage imageWithCIImage:imgCI];
In the line 5, the fileter.outputImage is nil and hence the final img is nil. I check the DNG file in Mac and it shows it is Adobe Raw. I also print the filter in console:
CIRAWFilterImpl: inputRequestedSushiMode=nil inputNeutralChromaticityX=0.5342335533653005 inputNeutralChromaticityY=0.4233451399853654 inputNeutralTemperature=2000 inputNeutralTint=9.616524016108169 inputNeutralLocation=[] inputEV=0 inputBoost=1 inputDraftMode=nil inputScaleFactor=1 inputIgnoreOrientation=nil inputImageOrientation=1 inputEnableSharpening=1 inputEnableNoiseTracking=1 inputEnableVendorLensCorrection=0 inputNoiseReductionAmount=0 inputLuminanceNoiseReductionAmount=nil inputColorNoiseReductionAmount=nil inputNoiseReductionSharpnessAmount=nil inputNoiseReductionContrastAmount=nil inputNoiseReductionDetailAmount=nil inputMoireAmount=nil inputDecoderVersion=nil inputBoostShadowAmount=nil inputBias=nil inputBaselineExposure=nil inputDisableGamutMap=0 inputHueMagMR=nil inputHueMagRY=nil inputHueMagYG=nil inputHueMagGC=nil inputHueMagCB=nil inputHueMagBM=nil inputLinearSpaceFilter=nil>
The inputDecoderVersion seems nil which may cause the problem(but I'm not sure).
The DNG files are downloaded from Internet, and I also try the NEF files which has the same result.
Could anyone give some advice?
It should run in real device.
In simulator, it returns nil.

converting video to NSData in share extension in ios

I have created a share extension for my ios app. When I click on the share option in the photo app my share extension is shown and I click on it and my controller is shown. Everything is working fine up to this. I am uploading video to youtube using the youtube api. I am using this method to create the parameter
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:fileData MIMEType:#"video/*"];
Now if the video is small then it is easily converted to NSData using this code
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:videoURL]];
and everything is working and video is uploaded.
But if the video is large then it simply crash and exit from the share extension(I put breakpoint and found this problem. If I remove the fileData conversion then its not crashing.). So what I did was instead of converting it to NSData I used this youtube api method
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithFileURL:[NSURL URLWithString:videoURL] MIMEType:#"video/*"];
Now app is not crashing but I am getting network error. The error is
Error Domain=NSURLErrorDomain Code=-995 "(null)"
little searching found that it is because of NSURLSession and told to use something like this
sessionConfiguration.sharedContainerIdentifier = #“com.me.myapp.containerIdentifier”;
I am using youtube api. I am not sure where to use it OR is there any other way to use youtube api in share extension with large video file.
NOTE: I am using youtube api in my app and its working fine with NSData.
Hope question is clear. I am stuck on it for a day now. Please help.
Thanks in advance.
EDIT 1:
I used this code
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoURL] options:0 error:&error];
filedata is nil. The error I am getting is
Error Domain=NSCocoaErrorDomain Code=260 "The file “IMG_2187.MOV”
couldn’t be opened because there is no such file."
UserInfo={NSFilePath=/file:/var/mobile/Media/DCIM/102APPLE/IMG_2187.MOV,
Consider this line:
var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL!
This does a forced unwrapping of info[UIImagePickerControllerMediaURL] (which is bad, because if it was nil, the app would crash) and that casts it as an implicitly unwrapped optional NSURL!. That doesn't make sense. Just do a conditional unwrapping (and unwrap to a NSURL, not a NSURL!):
if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL { ... }
The next line calls filePathURL:
var videoFileURL = videoDataURL.filePathURL
If you wanted a file URL, you already have one, so no conversion is needed, but instead just use videoDataURL. If you really wanted a path, you'd use path method:
let videoPath = videoDataURL.path
Frankly, Apple is trying to shift us away from using string paths, so just use the original videoDataURL and avoid the use of both path and filePathURL.
You are using dataWithContentsOfMappedFile:
var video = NSData.dataWithContentsOfMappedFile("\(videoDataURL)")
If you really wanted to use dataWithContentsOfMappedFile, the proper Swift syntax is:
let video = NSData(contentsOfMappedFile: videoPath!)
But dataWithContentsOfMappedFile deprecated, so you should instead use:
let video = try NSData(contentsOfFile: videoPath!, options: .DataReadingMappedIfSafe)
Or, bypassing that videoPath altogether, you could:
let video3 = try NSData(contentsOfURL: videoDataURL, options: .DataReadingMappedIfSafe)
Obviously, those try renditions should be done within a do block with a catch block.
By the way, as you'll see in all of my above examples, one should use let where possible.
Quite frankly, I would advise against loading it into a NSData at all. Just copy it with NSFileManager, which is a more efficient use of memory. If the video is long, it could be quite large, and you should avoid loading the whole thing into memory at any given point in time.
So you could:
if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL {
do {
// build your destination URL however you want
//
// let tempFolder = NSURL(fileURLWithPath: NSTemporaryDirectory())
// let destinationURL = tempFolder.URLByAppendingPathComponent("test.mov")
// or
let documents = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
let destinationURL = documents.URLByAppendingPathComponent("test.mov")
// but just copy from the video URL to the destination URL
try NSFileManager.defaultManager().copyItemAtURL(videoDataURL, toURL: destinationURL)
} catch {
print(error)
}
}
If you're uploading this to a web service, you'd then use a NSURLSessionUploadTask, using file or stream options. The construction of this request is a separate question, but hopefully you get the idea: With large assets like photos or, especially, videos, don't instantiate a NSData with the asset if you can possibly avoid it.
Please try this if your file exist in your phone instead of [NSURL URLWithString:videoURL].
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoURL]];

How to Upload Image file into dropbox?

I want to select image into gallery and that image i want to upload in dropbox.How can i do this?
i tried dropbox SDK but i do not know how to upload selected image
- (void)uploadFile:(NSString*)filename toPath:(NSString*)path fromPath:(NSString *)sourcePath
this method is defined in DBRestClient.h,a library file from the DropBox SDK for iOS. But as from the above declaration of the method, the "fromPath" of the image which is present in the UIImageView needs to be ascertained to upload it to my account on dropbox. Can you please help me in how to determine the path, or for that matter, any work around which can be applicable.
NSData *data = UIImagePNGRepresentation(imageView.image);
NSString *file = [NSTemporaryDirectory() stringByAppendingPathComponent:#"upload.png"];
[data writeToFile:file atomically:YES];
[DBRestClient uploadFile:#"upload.png" toPath:#"Dropbox/Path" fromPath:file];
Here is a tutorial of how to achieve that. It´s a couple of steps and hard to tell what you´re doing wrong, that´s why I have only included a link for the answer.
But basically
let uploadTextFileAction = UIAlertAction(title: "Upload text file", style: UIAlertActionStyle.Default) { (action) -> Void in
let uploadFilename = "testtext.txt"
let sourcePath = NSBundle.mainBundle().pathForResource("testtext", ofType: "txt")
let destinationPath = "/"
self.dbRestClient.uploadFile(uploadFilename, toPath: destinationPath, withParentRev: nil, fromPath: sourcePath)
}
I recommend you to check the tutorial, since there are some framework imports and other stuff that is required.

Copy GIF to UIPasteboard

I'm trying to copy a GIF image to the UIPasteboard in swift, at the moment it only copies the static version of the image and seems to convert it to PNG looking at the file extension when I upload it somewhere.
Wondered if anyone had any idea how to achieve this? All other soltions I've found only seem to work when getting NSData from a URL rather than from an image in the bundle
For anyone who ever encounters this problem I managed to find a solution
let url: NSURL = NSBundle.mainBundle().URLForResource("\(self.imageNames[indexPath.row])", withExtension: ".gif")!
let data: NSData = NSData(contentsOfURL: url)!
UIPasteboard.generalPasteboard().setData(data, forPasteboardType: "com.compuserve.gif")
As it turns out you do need to use a URL and extract the NSData of the GIF from that URL.
Here I am getting the URL of the GIF that is in my bundle, searching for it using the name and extension of the image. I am then setting the data in the pasteboard and bingo we have an animated GIF when pasting the result from the pasteboard
It doesn't look like the image property on the pasteboard supports the GIF type.
The associated array of representation types is UIPasteboardTypeListImage, which includes types kUTTypePNG and kUTTypeJPEG.
You could probably do this using the NSData from the GIF though:
import MobileCoreServices
// ...
var image = UIImage(...)
let data = NSData(bytes: &image, length: sizeof(UIImage))
UIPasteboard.generalPasteboard().setData(data, forPasteboardType: kUTTypeGIF as String)) // com.compuserve.gif

Printing PDF on iOS, background image not printing

I'm attempting to print a PDF file in my Cordova application on iOS.
The file is generated using jsPDF in the Cordova app and then I've modified the katzer cordova-plugin-printer to accept the raw PDF data as a string, convert it to NSData and print it out.
- (void) printPDFFromData:(CDVInvokedUrlCommand*)command
{
if (!self.isPrintingAvailable)
{
return;
}
NSArray* arguments = [command arguments];
NSString* documentData = [arguments objectAtIndex:0];
NSData* pdfData = [documentData dataUsingEncoding:NSUTF8StringEncoding];
UIPrintInteractionController* controller = printController;
[self adjustSettingsForPrintController:controller];
controller.printingItem = pdfData;
[self openPrintController:controller];
[self commandDelegate];
}
Using the iOS print simulator (I don't have access to an AirPrint printer), the PDF appears to print out, except that the background image is not printed, just the vector drawings overlaying it.
The same raw output data when saved to a PDF file will display the background image and when you print that file, the background image is printed.
Is this just an anomaly of the printer simulator or do I need to somehow set the print controller to be able to print the image in the document?
I found a solution to the issue. Something was getting lost in the decoding of the string data from JavaScript into Objective-C.
To get around this I Base64 encoded the PDF document in my JS side before sending it off to the plugin:
var startIndexOfBase64Data = 28;
var base64Document = doc.output('dataurlstring').substring(startIndexOfBase64Data);
window.plugin.printer.printPDFFromData(base64Document);
Then I needed to add
NSData+Base64.m and NSData+Base64.h
from this sample project into my plugins directory to allow this line of code to convert the Base64 string into NSData:
NSData* pdfData = [NSData dataFromBase64String:documentData];
Then the document then printed out untainted.
Now I'm off to see if I can get it working with Android.

Resources