Creating an image from NSData and saving it using PHPhotoLibrary - ios

I am tring to create an image using the NSData collected from Bluetooth. The data is saved in NSData variable recdata which is then converted to image using imageWithData. I am trying to save this image to the Photo library using the code below. But I don't see the image in the photo library. Am I missing something??
Also, as I am doing this project where I am receiving the data from bluetooth, I don't know how to check the error message on my iPhone screen. Currently, I am using the [information setText:[NSString stringWithFormat:#"%#", error.localizedFailureReason ]]; from the completionhandler to print the error message. But nothing gets printed and the app crashes and closes down.
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
//PHAssetResourceType assetType = PHAssetResourceTypePhoto;
UIImage *image = [UIImage imageWithData:recdata];
[PHAssetChangeRequest creationRequestForAssetFromImage: image];
[information setText:[NSString stringWithFormat:#"Krishna"]];
//PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage: image];
//PHAssetResourceCreationOptions *creationOptions = nil;
//creationOptions.originalFilename = command1; // Name of the file to be taken from command1
//[request addResourceWithType:assetType data:rxdata options:creationOptions]; //rxdata has all the data needed for the file to be transferred to the final image file.
} completionHandler:^(BOOL success, NSError *error) {
[information setText:[NSString stringWithFormat:#"%#", error.localizedFailureReason ]];
}];

Related

PhotoKit - didFinishPickingMediaWithInfo vs creationRequestForAssetFromImage (data not equal??)

Wanted to get some feedback to see what I might be missing here. Basically I use a UIImagePickerViewController to take a photo. When I am done i retrieve this image like this:
UIImage *photoTaken = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
After I have taken the photo, at a later time, I need to be able load all the images in my camera roll and highlight the photo(I display all the images from the camera roll) that I just took. Because these photos are different objects in memory (different view controllers), the only way to compare them is by comparing the actual data that represents the images. i..e..
NSData *alreadySelectedPhotoData = UIImageJPEGRepresentation(alreadySelectedPhoto.photoImage, 0.0);
NSData *cameralRollPhotoData = UIImageJPEGRepresentation(cameraRollPhoto.photoImage, 0.0);
if([cameralRollPhotoData isEqualToData:alreadySelectedPhotoData]){
//do something here if they are equal(draw a border, etc)
}
However, the photos never actually were equal based on this comparison, despite the fact that the images displayed are identical.
So I went back to the original code, did some digging and did a data and visual test:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
__block UIImage *photoTaken = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
__block PHObjectPlaceholder *placeholderAsset = nil;
//save our new photo to the camera roll album(successfully)
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:photoTaken];
changeRequest.creationDate = creationTimeStamp = [NSDate date];
placeholderAsset = changeRequest.placeholderForCreatedAsset;
}
completionHandler:^(BOOL success, NSError *error){
PHImageManager *manager = [PHImageManager defaultManager];
PHImageRequestOptions *requestOptions = [PHImageRequestOptions new];
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
CGFloat dimension = [UIScreen mainScreen].bounds.size.width / 3 * [UIScreen mainScreen].scale;
CGSize targetSize = CGSizeMake(dimension, dimension);
PHFetchResult *savedAssets = [PHAsset fetchAssetsWithLocalIdentifiers:#[placeholderAsset.localIdentifier] options:nil];
[manager requestImageForAsset:savedAssets.firstObject targetSize:targetSize contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage *result, NSDictionary *info) {
//images are the 'same' but their NSData representations appear to not be. NSLog statement never executes.
NSData *alreadySelectedPhotoData = UIImageJPEGRepresentation(photoTaken, 0.0);
NSData *cameralRollPhotoData = UIImageJPEGRepresentation(result, 0.0);
if([cameralRollPhotoData isEqualToData:alreadySelectedPhotoData]){
NSLog(#"images are equal");
}
}];
}];
So to summarize:
store the image that comes back from the info object in the picker delegate method
use this image and store it in the camera roll by using 'creationRequestForAssetFromImage'
retrieve back the image that we just stored by getting Asset ('fetchAssetsWithLocalIdentifiers')
convert that asset back into an image (PHManager - requestImageForAsset)
convert both the original UIImage that was returned via the picker delegate and the image back from the camera roll that was created to NSData objects.
Result: they do not equal, even though the images on the screen are exactly the same.
Conclusion: It seems to me that this below:
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:photoTaken];
saves to the camera roll successfully, can verify that the image it displays is exactly the image that I got from the UIPickerImage delegate method(visually looks the same), yet when converting both images to NSData objects the comparison fails.
Does anyone have any idea whats going on here? did I miss something or is this a bug?

How do I upload image Podio SDK using Objective-C (iOS)?

I am integrating the Podio SDK. I am getting all data item values and updating also, but images won't upload. Any idea? I don't know how to upload an image on Podio SDK.
NSData *data = UIImageJPEGRepresentation(self.ImgView_Sign.image, 0.8f);
[[[PKTFile uploadWithData:data fileName:#"mobi.jpg"] pipe:^PKTAsyncTask *(PKTFile *file){
PKTItem *item = [PKTItem itemForAppWithID:431525395];
item[#"title"] = #"CHEKRI";
item[#"signautre"] = file;
return [item save];
}] onSuccess:^(PKTItem *item){
NSLog(#"PKT FILE is %#",item);
} onError:^(NSError *error){
NSLog(#"Error file %#",error);
}];
Please use below code might be work for you.
UIImage *image = [UIImage imageNamed:#"some-image.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 0.8f);
PKTAsyncTask *uploadTask = [PKTFile uploadWithData:data fileName:#"image.jpg"];
[uploadTask onComplete:^(PKTFile *file, NSError *error) {
if (!error) {
NSLog(#"File uploaded with ID: %#", #(file.fileID));
}
}];
Adding an image to an image field is a two-step process.
First you must upload the file. https://developers.podio.com/doc/files/upload-file-1004361 will give you a file object with a file_id you need in step two.
Step two is to create a new item, update an item or update the field value. Here you pass the file_id as a the value for the field.
We have a general tutorial on working with items here https://developers.podio.com/examples/items
Working with file_ids for image fields is not different than the other field types. Just as you use profile_ids to work with Contact fields you use file_ids to work with image fields.
Original source: https://help.podio.com/hc/en-us/community/posts/200516608-API-image-upload-to-Image-Field

app about remove duplicate photos from photos app

I am creating an Application that fetches Images from the photo library of the phone and remove duplicate images from it.I searched a lot but did not find any way to delete the image from the photo library.
i create on demo for that
here is the code
i used UIImageJPEGRepresentation to convert image into data.and compare them it gives me result.is there any other image property that we can compare?
UIImage *img1 = [UIImage imageNamed:#"1.jpg"];
UIImage *img2 = [UIImage imageNamed:#"2.jpg"];
NSData *data1 = UIImageJPEGRepresentation(img1, 1.0);
NSLog(#"%#",data1);
NSData *data2 = UIImageJPEGRepresentation(img2, 1.0);
NSLog(#"%#",data2);
if ([data1 isEqualToData:data2])
{
NSLog(#"yes");
}
else
{
NSLog(#"no");
}
As you know we dont have access to modify anything out side the sandbox.So before ios 8 it was not possible to delete photos from photo library.But in ios 8 and later versions are supported to delete photos from library but before removing it will ask user that you want to delete photos.If user allow then photos will be deleted.
I providing you the CODE which I have used in my app to delete photo from photo library.
if (check system version >= 8.0)
{
PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
[library performChanges:^{
PHFetchResult *assetsToBeDeleted = [PHAsset fetchAssetsWithALAssetURLs:delet
options:nil];
[PHAssetChangeRequest deleteAssets:assetsToBeDeleted];
} completionHandler:^(BOOL success, NSError *error) {
//do something here when error
}];
}
Where delet is the array of asset url of images you get from library with help of AssetLibrary framework.
PHFetchResult *moments = [PHAssetCollection fetchMomentsWithOptions:nil];
for (PHAssetCollection *moment in moments)
{
PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsInAssetCollection:moment options:nil];
for (PHAsset *asset in assetsFetchResults)
{
// Do something with assets, for example add them to array.
}
}

Setting the location property of PHAssetChangeRequest doesn't create a GPS section in image metatdata

When a picture is taken (iOS 8.1) and didFinishPickingMediaWithInfo is called, I'm trying to use PhotoKit to add the GPS data back into the metadata.
This is the code I'm using:
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
newAssetRequest.creationDate = [NSDate date];
newAssetRequest.location = [self deviceLocation];
NSLog(#"didFinishPickingMediaWithInfo: location:%#", newAssetRequest.location);
PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
PHAssetCollectionChangeRequest *addAssetRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.myResults[0]];
[addAssetRequest addAssets:#[placeholderAsset]];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"didFinishPickingMediaWithInfo: Success saving picture to album");
} else {
NSLog(#"didFinishPickingMediaWithInfo: error saving picture to album %#", error);
}
}];
[picker dismissViewControllerAnimated:YES completion:nil];
The code takes the image and moves it to an album. This part works. The photo ends up in the correct album.
The problem is the GPS data is not present in the metadata even though the location property is properly set. I know the location data is valid.
Shouldn't this work? Is there an alternate approach to get the desired result? I don't really care about all the other metadata, just the GPS coordinates.

iOS - Is it possible to rename image file name before saving it into iPhone device gallery from app?

Hey I'm new to iPhone and I have been trying to make an gallery kind of app. Basically, what I want to do is that i need to save all the captured images into a specific folder like a new album "My_App Images" related to our app name in iPhone device gallery, it's working for me, but I am having trouble to change the image file name, i don't know that Is it possible to specify a file name? Using iPhoto, currently i am getting image file name as "IMG_0094.jpg", can we change it with any other file name like "Anyfilename.png" format programmatically?
here is my code for saving images to the specific album :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[self.library saveImage:image toAlbum:#"My_App Images" withCompletionBlock:^(NSError *error) {
if (error!=nil) {
NSLog(#"Image saving error: %#", [error description]);
}
}];
[picker dismissViewControllerAnimated:NO completion:nil];
}
Any source or link for reference is appreciated. Thanks for the help!
There is a way to kinda do that, by setting the image IPTC metadata field "Object Name". If you later import the image to iPhoto, then this name will be used as its title.
See details (and code) at http://ootips.org/yonat/how-to-set-the-image-name-when-saving-to-the-camera-roll/ .
Do you meant,
// Build NSData in memory from the btnImage...
NSData* imageData = UIImageJPEGRepresentation(image, 1.0);
// Save to the default Apple (Camera Roll) folder.
[imageData writeToFile:#"/private/var/mobile/Media/DCIM/100APPLE/customImageFilename.jpg" atomically:NO];
Now adjust the path of folder as per your folder name...
Sorry to disappoint you, but it seems that you can not change the name of the photos, before or after saving, in the photo album, custom or not. Here is a post to explain it:
iOS rename/delete albums of photos
Edit
So, to clarify my comment, use the following override:
Download the NSMutableDictionary category for metadata of image here.
Also download the sample project CustomAlbumDemo from here and modify the NSMutableDictionary+ImageMetadata.m file in the CustomAlbumDemo project as:
-(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock
{
//write the image data to the assets library (camera roll)
NSData* imageData = UIImageJPEGRepresentation(image, 1.0);
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
[metadata setDescription:#"This is my special image"];
[self writeImageDataToSavedPhotosAlbum:imageData metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {
//error handling
if (error!=nil) {
completionBlock(error);
return;
}
//add the asset to the custom photo album
[self addAssetURL: assetURL
toAlbum:albumName
withCompletionBlock:completionBlock];
}];
}

Resources