raw CIFilter has nil outputImage - ios

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.

Related

Is HEIC/HEIF Supported By UIImage

I was under the impression that UIImage would support HEIC/HEIF files introduced in iOS 11. In my testing that does not appear to be the case though. If I do let image = UIImage(named: "test") which points to test.heic then image is nil. If I use an image literal then it crashes the app. Wondering if this is not implemented yet for now. Thanks.
While Zhao's answer works, it is fairly slow. The below is about 10-20 times faster. It still doesn't work in the simulator for some reason though so keep that in mind.
func convert(url: URL) -> UIImage? {
guard let source = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }
guard let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil) else { return nil }
return UIImage(cgImage: cgImage)
}
This is kind of outlined on page 141 from the slides of a WWDC session but wasn't super clear to me before: https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf
Unfortunately I still haven't been able to figure out a way to use images in the xcassets folder so you'll either have to include the files outside of assets or pull from on the web. If anyone knows a way around this please post.
In Xcode 10.1 (10B61), UIImage(named: "YourHeifImage") works just like other assets.
Interestingly though, when you want to try this out …and you AirDrop a HEIF pic from your (e.g. iPhone) Photos to your mac, it will get the extension .HEIC (all caps). When you then add that image to your Xcode xcassets, Xcode complains about an incorrect extension:
….xcassets: warning: Ambiguous Content: The image set "IMG_1791" references a file "IMG_1791.HEIC", but that file does not have a valid extension.
If you first change the extension to the lower-case .heic, and then add it to xcassets, all is well.
You can load HEIF via CIImage, then convert to UIImage
CIImage *ciImage = [CIImage imageWithContentsOfURL:url];
imageView.image = [UIImage imageWithCIImage:ciImage];

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.

UIImage imageWithData returns nil

I'm developing an iOS 5.0+ app with latest SDK.
On my app I have some C++ image recognition software, and I'm trying to save image recognized by this C++ functions.
I have this array to store image recognized:
int _detectedImages[NSMaxNumDetections ][NSPatchSize * NSPatchSize];
I call the C++ function this way:
numberOfDetections = nativeDetect(_resultImages);
And with the following code, I try to convert data from _detectedImages to UIImage.
for (int index = 0; index < numberOfDetections; index++)
{
if (_resultImages[index] != nil)
{
NSData* imageData = [NSData dataWithBytes:&_resultImages[index] length:sizeof(_resultImages[index])];
NSLog(#"##### Image data size: %d", [imageData length]);
UIImage* newImage = [UIImage imageWithData:imageData];
_lastDetectedSignImages[index] = newImage;
}
}
On the log I get this:
#### Image data size: 2304
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM setObject:atIndex:]: object cannot be nil'
*** First throw call stack:
newImage is nil but imageData has data.
Am I doing something wrong when I try to get an UIImage from that data?
The other possibility if that my C++ recognition software is doing something wrong, but I'm not going to show you that code here (sorry, it's copyrighted).
Or I'm not passing _resultImages correctly to nativeDetect.
Almost for sure your C++ images are in some bitmap format - RGBA etc. So your first task is to figure out what that format is (and the byte order too!). With that information you can use CGImageCreate() to create a CGImageRef. With that you can create a UIImage.

CGImageSourceCreateImageAtIndex returns nil

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.

JPG image doesn't load with UIImage imageNamed

I read on the reference that from iOS version 4.+ with the method imageNamed of UIImage object, the file extension is not required.
From UIImage class reference:
Special Considerations.
On iOS 4 and later, the name of the file is not required to specify
the filename extension. Prior to iOS 4, you must specify the filename
extension.
But it seems that this only work with PNG files.
If my code is:
[UIImage imageNamed:#"test"];
The image loads only if the file is test.png
The image doesn't load if it's test.jpg.
For me it is a big problem because I need to maintain a dynamic image loading (I do not know at runtime if the image I want to load is png or jpg).
Please can you help me?
Thanks.
The latest developer reference states the missing piece of information:
Special Considerations
On iOS 4 and later, if the file is in PNG format, it is not necessary to specify the .PNG filename extension. Prior to iOS 4, you must specify the filename extension.
One possible reason that the library gives PNGs special treatment, is that the iOS hardware is optimized for PNGs. PNG images stored in the application bundle are optimized by Xcode, changing the byte order of the PNG images to match the graphics chip of the iPhone device. (see this question: Is PNG preferred over JPEG for all image files on iOS?).
If you know that you will only have a PNG or a JPG, an alternative solution is to create a category on UIImage as per below.
- (UIImage*) jgcLoadPNGorJPGImageWithName:(NSString*)name {
UIImage * value;
if (nil != name) {
value = [UIImage imageNamed:name];
if (nil == value) {
NSString * jpgName = [NSString stringWithFormat:#"%#.jpg", name];
value = [UIImage imageNamed:jpgName];
}
}
return value;
}
If you have these images bundled in your app, you SHOULD know their extensions.
If you're getting them from an online source and you have them as NSData, you can use this code here to determine the type.
+ (NSString *)contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return #"image/jpeg";
case 0x89:
return #"image/png";
case 0x47:
return #"image/gif";
case 0x49:
case 0x4D:
return #"image/tiff";
}
return nil;
}
As per the top answer in this question.

Resources