Showing posts with label uiimage. Show all posts
Showing posts with label uiimage. Show all posts

Tuesday, August 28, 2018

Multiple images not getting saved in Photo Library by using UIActivityViewController

Leave a Comment

I need to save multiple images in the photo library, the user can multiple selects the images from the app gallery then can save them in iPhone Photo Gallery. I am showing the UIActivityViewController for the purpose.

Suppose a user selects 10 or more images and choose to save them into photo library then only 7-8 images are saved.

Is there any way by which i can save array of images in the photo library without any failure ?

Thanks

let images = Generic.fetchImagesFromMediaFiles(self.selectedMediaObj) // to fetch selected images  let activityViewController = UIActivityViewController(activityItems: images, applicationActivities: nil) self.present(activityViewController, animated: true, completion: nil);  if let popoverPresentationController = activityViewController.popoverPresentationController {     popoverPresentationController.sourceView = self.shareAllView } 

2 Answers

Answers 1

iOS system write photo save to album use single thread, one by one to do. if you want to save more photos same time, it maybe loss some data.

-(void)saveBtn { [SSGOTools againRequestPhotoWithblock:^(BOOL isAgree) { if (isAgree) {  self.listOfImages = [NSMutableArray new]; int photoNum ; photoNum = (int)_photoArray.count; if (_photoArray.count > 9) { photoNum = 9; } for (int i = 0; i < photoNum; i++) { NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_photoArray[i]]]; UIImage *myImage = [UIImage imageWithData:data]; //[self.listOfImages addObject:myImage]; [self loadImageFinished:myImage];  } } }]; }  - (void)loadImageFinished:(UIImage *)image { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{  //write photo save to album  [PHAssetChangeRequest creationRequestForAssetFromImage:image];  } completionHandler:^(BOOL success, NSError * _Nullable error) {  NSLog(@"success = %d, error = %@", success, error); if(success){ dispatch_async(dispatch_get_main_queue(), ^{ [SSGOTools showInfoPopHint:@"Success"]; }); } }]; } 

Answers 2

you will need to use the completion block here for ensuring all images are saved.. try this :

-(void)saveBtn{ [SSGOTools againRequestPhotoWithblock:^(BOOL isAgree) {     if (isAgree) {         self.listOfImages = [NSMutableArray new];         int photoNum ;         photoNum = (int)_photoArray.count;         if (_photoArray.count > 9) {             photoNum = 9;         }         for (int i = 0; i < photoNum; i++) {             NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_photoArray[i]]];             UIImage *myImage = [UIImage imageWithData:data];             [self.listOfImages addObject:myImage];            // [self loadImageFinished:myImage];         }        [self saveAllImages:self.listOfImages];     } }]; } -(void)saveAllImages:(NSMutableArray *)images { UIImage *image = [images firstObject]; [images removeObject:image];  [self loadImageFinished:image :^(bool success) {      if (success){          if (images.count > 0){             [self saveAllImages:images];         }else{             // all images saved do whatever you want;         }      }else{         NSLog(@"failed saving image");     }  }]; } - (void)loadImageFinished:(UIImage *)image :(void(^)(bool success))completion{ [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{      //write photo save to album      [PHAssetChangeRequest creationRequestForAssetFromImage:image];  } completionHandler:^(BOOL success, NSError * _Nullable error) {      NSLog(@"success = %d, error = %@", success, error);     if(success){         dispatch_async(dispatch_get_main_queue(), ^{             [SSGOTools showInfoPopHint:@"Success"];         });     }     completion(success); }]; } 
Read More

Saturday, September 30, 2017

Making video from UIImage array with different transition animations

Leave a Comment

I am following this code to create Video from an UIImage Array. While transitioning from one image to another, there is no animation here. I want to add some photo transition effect like these :

  1. TransitionFlipFromTop
  2. TransitionFlipFromBottom
  3. TransitionFlipFromLeft
  4. TransitionFlipFromRight
  5. TransitionCurlUp
  6. TransitionCurlDown
  7. TransitionCrossDissolve
  8. FadeIn
  9. FadeOut

These animations can be done via UIView.transition() & UIView.animate().

But how to apply these transition animations while making a video from an UIImage array? I have searched a lot but didn't find anything.

I've also tried HJImagesToVideo but it offers only Crossfade transition .

0 Answers

Read More

Wednesday, September 6, 2017

Issue with add watermark on video

Leave a Comment

I am trying to add an image on a video. Everything works fine except one thing, the image is distorted:

enter image description here

Here is the code :

//Capture the image UIGraphicsBeginImageContextWithOptions(self.captureView.bounds.size, false, UIScreen.main.scale) self.captureView.layer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()  let watermarkVideo = WatermakVideo()  //video file let videoFile = Bundle.main.path(forResource: "videoTrim", ofType: "mp4") let videoURL = URL(fileURLWithPath: videoFile!)  let imageFrame = captureView.frame watermarkVideo.createWatermark(image, frame: imageFrame, video: videoURL) 

Here is the class WatermakVideo : https://www.dropbox.com/s/0d6i7ap9qu4klp5/WatermakVideo.zip

I would be grateful if you could help me fix this issue.

1 Answers

Answers 1

Copy the below into your file. I had the same issue and solved the problem two weeks ago:

-(void)forStackOverflow:(NSURL*)url{ AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:url options:nil];     AVMutableComposition* mixComposition = [AVMutableComposition composition];      AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];     AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];     AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];     AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];     //If you need audio as well add the Asset Track for audio here      [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];     [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];      [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];        CGSize sizeOfVideo=compositionVideoTrack.naturalSize;      CGFloat scaleWidth = sizeOfVideo.height/self.view.frame.size.width;     CGFloat scaleHeight = sizeOfVideo.width/self.view.frame.size.height;      // add image     UIImage *myImage=[UIImage imageNamed:@"YOUR IMAGE PATH"];     CALayer *layerCa = [CALayer layer];     layerCa.contents = (id)myImage.CGImage;     layerCa.frame = CGRectMake(5*scaleWidth, 0, self.birdSize.width*scaleWidth, self.birdSize.height*scaleWidth);     layerCa.opacity = 1.0;      // add Text on image     CATextLayer *textOfvideo=[[CATextLayer alloc] init];     textOfvideo.alignmentMode = kCAAlignmentLeft;     [textOfvideo setFont:(__bridge CFTypeRef)([UIFont fontWithName:@"Arial" size:64.00])];//fontUsed is the name of font     [textOfvideo setFrame:CGRectMake(layerCa.frame.size.width/6, layerCa.frame.size.height/8*7-layerCa.frame.size.height/3, layerCa.frame.size.width/1.5, layerCa.frame.size.height/3)];     [textOfvideo setAlignmentMode:kCAAlignmentCenter];     [textOfvideo setForegroundColor:[[UIColor redColor] CGColor]];      UILabel*label = [[UILabel alloc]init];     [label setText:self.questionString];     label.textAlignment = NSTextAlignmentCenter;     label.numberOfLines = 4;     label.adjustsFontSizeToFitWidth = YES;     [label setFont:[UIFont fontWithName:@"Arial" size:64.00]];     //[label.layer setBackgroundColor:[[UIColor blackColor] CGColor]];     [label.layer setFrame:CGRectMake(0, 0, textOfvideo.frame.size.width, textOfvideo.frame.size.height)];     [textOfvideo addSublayer:label.layer];       [layerCa addSublayer:textOfvideo];        CALayer *parentLayer=[CALayer layer];     CALayer *videoLayer=[CALayer layer];     parentLayer.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height);     videoLayer.frame=CGRectMake(0, 0, sizeOfVideo.height,sizeOfVideo.width);     [parentLayer addSublayer:videoLayer];     //[parentLayer addSublayer:optionalLayer];     [parentLayer addSublayer:layerCa];      [parentLayer setBackgroundColor:[UIColor blueColor].CGColor];        AVMutableVideoComposition *videoComposition=[AVMutableVideoComposition videoComposition] ;     videoComposition.frameDuration=CMTimeMake(1, 30);     videoComposition.animationTool=[AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];      //AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];     AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];     instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);     AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];     AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];      UIImageOrientation videoAssetOrientation_  = UIImageOrientationUp;     BOOL isVideoAssetPortrait_  = NO;     [layerInstruction setTransform:videoTrack.preferredTransform atTime:kCMTimeZero];       CGSize naturalSize;     naturalSize = videoTrack.naturalSize;       float renderWidth, renderHeight;     renderWidth = naturalSize.width;     renderHeight = naturalSize.height;     videoComposition.renderSize = naturalSize = CGSizeMake(videoTrack.naturalSize.height, videoTrack.naturalSize.width);       instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];     videoComposition.instructions = [NSArray arrayWithObject: instruction];      NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];     NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];     [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];     NSString *destinationPath = [documentsDirectory stringByAppendingFormat:@"/utput_%@.mov", [dateFormatter stringFromDate:[NSDate date]]];      AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];     exportSession.videoComposition=videoComposition;      exportSession.outputURL = [NSURL fileURLWithPath:destinationPath];     exportSession.outputFileType = AVFileTypeQuickTimeMovie;     [exportSession exportAsynchronouslyWithCompletionHandler:^{         switch (exportSession.status)         {             case AVAssetExportSessionStatusCompleted:                 NSLog(@"Export OK");                 if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(destinationPath)) {                     UISaveVideoAtPathToSavedPhotosAlbum(destinationPath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);                 }                 break;             case AVAssetExportSessionStatusFailed:                 NSLog (@"AVAssetExportSessionStatusFailed: %@", exportSession.error);                 break;             case AVAssetExportSessionStatusCancelled:                 NSLog(@"Export Cancelled");                 break;         }         self.currentUrl = exportSession.outputURL;         dispatch_async(dispatch_get_main_queue(), ^{          });       }]; } 
Read More

Sunday, September 3, 2017

ios Image text and colour enhancement filter

Leave a Comment

I am trying CIFilter and GPUImage filter to apply various effects (brightness, contrast, saturation, etc.) on an image, but I'm struggling, would need an enhancement like the one shown below:

Before Enhancement filter

Before Enhancement filter:

After Enhancement filter

After Enhancement filter

CIFilter code that I tried:

NSDictionary *options = @{ CIDetectorImageOrientation :                                [[resultImage properties] valueForKey:kCGImagePropertyOrientation] }; NSArray *adjustments = [resultImage autoAdjustmentFiltersWithOptions:options]; for (CIFilter *filter in adjustments) {     [filter setValue:resultImage forKey:kCIInputImageKey];     resultImage = filter.outputImage; } 

GPUImage Filter:

UIImage *inputImage = [UIImage imageNamed:@"Msource.png"]; GPUImageAdaptiveThresholdFilter *stillImageFilter = [[GPUImageAdaptiveThresholdFilter alloc] init]; stillImageFilter.blurRadiusInPixels = 10.0;// adjust this to tweak the blur radius of the filter, defaults to 4.0  UIImage *filteredImage = [stillImageFilter imageByFilteringImage:inputImage]; 

1 Answers

Answers 1

//Hope this helps , its in swift 3 :

        var aCIImage = CIImage();         var contrastFilter: CIFilter!;         var brightnessFilter: CIFilter!;         var gaussianBlurFilter: CIFilter!;         var pointFilter: CIFilter!;         var vignettFilter : CIFilter!;         var context = CIContext();         var outputImage = CIImage();         var newUIImage = UIImage();         var finalImage = UIImage()         DispatchQueue.main.async                         {                             self.gaussianBlurFilter = CIFilter(name: "CIExposureAdjust");                             self.gaussianBlurFilter.setValue(self.aCIImage, forKey: "inputImage")                              self.gaussianBlurFilter.setValue(NSNumber(value: sender.value), forKey: "inputEV");                              self.outputImage = self.gaussianBlurFilter.outputImage!;                              let imageRef = self.context.createCGImage(self.outputImage, from: self.outputImage.extent)                              self.newUIImage = UIImage(cgImage: imageRef!)                             self.testView?.image = self.newUIImage;                     }    //  

enter image description here

Read More

Tuesday, March 21, 2017

Open CV memory stacked (not released properly)

Leave a Comment

I am using 3rd party library for image processing, this method seems to be the cause of large memory usage (+30MB) everytime it executed, and it won't release properly. Repeated use of it ends up crashing the app (memory overload).

+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat {     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((__bridge 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 *image = [[UIImage alloc] initWithCGImage:imageRef];     UIImage *image = [UIImage imageWithCGImage:imageRef];      CGImageRelease(imageRef);     CGDataProviderRelease(provider);     CGColorSpaceRelease(colorSpace);      return image; } 

I suspect the problem is here: (__bridge CFDataRef)data. I cant use CFRelease on it cause it make app crash. Project is running with ARC.

EDIT:

It seems the same code is also in openCV official website: http://docs.opencv.org/2.4/doc/tutorials/ios/image_manipulation/image_manipulation.html

Gah!

EDIT 2 Here is the code how I use it (actually below code is also a part of the 3rd party lib, but i added some lines).

 cv::Mat undistorted = cv::Mat( cvSize(maxWidth,maxHeight), CV_8UC4); // here nothing         cv::Mat original = [MMOpenCVHelper cvMatFromUIImage:_adjustedImage]; // here +30MB          //NSLog(@"%f %f %f %f",ptBottomLeft.x,ptBottomRight.x,ptTopRight.x,ptTopLeft.x);         cv::warpPerspective(original, undistorted,                             cv::getPerspectiveTransform(src, dst), cvSize(maxWidth, maxHeight)); // here +16MB (PROBLEM)            _cropRect.hidden=YES;          @autoreleasepool {             _sourceImageView.image=[MMOpenCVHelper UIImageFromCVMat:undistorted]; // here +15MB (PROBLEM)         }                   original.release(); // here -30MB (THIS IS OK)         undistorted.release(); // here nothing 

0 Answers

Read More

Thursday, January 26, 2017

Can't pan image taken from camera with UIImagePicker

Leave a Comment

I'm using a UIImagePicker to get the user to take a photo. When the photo is taken, I want them to pan and zoom the image around to fit inside the cropped box so that the image is stored as a square.

However, when cropping the image, it seems as though you cannot move it to the top and bottom of a (portrait) image (left and right if landscape).

I have tried searching but there doesn't seem to be much information, but it seems like a massive issue.

Can someone help?

This is the very small amount of code I'm using:

let imagePicker = UIImagePickerController()  imagePicker.allowsEditing = true imagePicker.sourceType = UIImagePickerControllerSourceType.camera  present(imagePicker, animated: true, completion: nil) 

There's obviously more code but this is the main part.

EDIT with photo:

enter image description here

So I want to be able to move the photo around/zoom in to select any square portion to save. However, I cannot move it from this position/ keeps snapping back.

I can zoom in, but it still restricts me from the top and bottom edges.

Again, it works with the photoLibrary.

3 Answers

Answers 1

This is a bug that was introduced in iOS 6 and hasn't been fixed yet.

A radar was raised in 2012 for this but closed by Apple. I managed to get it opened again and have been pestering Apple devs in my contacts for the past 6 months.

http://openradar.appspot.com/12318774

Until this is fixed by Apple the only option is to use a third party control or do it yourself.

Here is the radar I opened...

http://openradar.appspot.com/28260087

Answers 2

I know you said it already zooms but you may just need to adjust the bounds for that.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {     image.image = info[UIImagePickerControllerEditedImage] as? UIImage     self.dismiss(animated: true, completion: nil) } 

You may also need to use CGRect to set the image correctly in the screen. It should be centered. If you are using and iphone 5 the dimensions 640 x 1136.

This happens because the width or the height of the image gets maxed out to the screen.

Answers 3

I have used the solution provided at below link:-

https://github.com/Hipo/HIPImageCropper

It handles the landscape and potrait allignment of the image and provides zoom in and zoom out with crop functionality.

Hope this helps.

Read More

Wednesday, March 30, 2016

Update image of NSTextAttachment once already rendered

Leave a Comment

I have an NSTextAttachment which I want to show a loading image until the image has downloaded and then once it has I want to update the image.

I have all of the logic in place, except when I call textAttachment.image = image the second time nothing happens.

How can I update the NSTextAttachment once it has already been rendered by the UITextView?

Thanks!

1 Answers

Answers 1

You must always update the user interface from the main thread, not from the socket thread.

Here is a Swift example:

// Update UI from main thread dispatch_async(dispatch_get_main_queue(), {   textAttachment.image = image })
Read More