I am having an app in which I am sharing an image on instagram and it works perfectly fine.
As shown in the screenshot. When I press the button share on instagram it opens up in UIActivityviewcontroller.
Is it possible that If I click on Share on Instagram and and it takes me directly to the native instagram app?
If the user has other apps installed in his device that apps also shows because of the UIActivityViewController.
I don't want to show UIActivityviewcontroller saying "Open In Instagram".
Thanks in advance.
Edited
I am taking a screenshot of a view and sharing that screenshot on Instagram.
When I click on a button share it opens up as shown in the screenshot which I don't want.
I am using the below code.
NSURL *instagramURL = [NSURL URLWithString:#"instagram://"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
CGRect rect = CGRectMake(0 ,0 , 0, 0);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndImageContext();
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
imagename=[NSString stringWithFormat:#"ff.ig"];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imagename];
////NSLog(#"%#",fullPathToFile);
igImageHookFile = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:#"file://%#", fullPathToFile]];
self.dic.UTI = #"com.instagram.photo";
self.dic = [self setupControllerWithURL:igImageHookFile usingDelegate:self];
self.dic=[UIDocumentInteractionController interactionControllerWithURL:igImageHookFile];
self.dic.annotation = [NSDictionary dictionaryWithObject:#"Image" forKey:#"InstagramCaption"];
[self.dic presentOpenInMenuFromRect: rect inView:self.view animated: YES ];
}
for swift
var instagramURL = NSURL(string: "instagram://app")!
if UIApplication.sharedApplication().canOpenURL(instagramURL) {
var documentDirectory = NSHomeDirectory().stringByAppendingPathComponent("Documents")
var saveImagePath = documentDirectory.stringByAppendingPathComponent("Image.igo")
var imageData = UIImagePNGRepresentation(self.bestScoreShareView.takeSnapshot(W: 640, H: 640))
imageData.writeToFile(saveImagePath, atomically: true)
var imageURL = NSURL.fileURLWithPath(saveImagePath)!
docController = UIDocumentInteractionController()
docController.delegate = self
docController.UTI = "com.instagram.exclusivegram"
docController.URL = imageURL
docController.presentOpenInMenuFromRect(CGRectZero, inView: self.view, animated: true)
} else {
println("instagram not found")
}
extension for take shapshot from uiview
extension UIView {
func takeSnapshot(#W: CGFloat, H: CGFloat) -> UIImage {
var cropRect = CGRectMake(0, 0, 600, 600)
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
image.imageWithNewSize(CGSizeMake(W, H))
return image
}
}
extension for set image size
extension UIImage {
func imageWithNewSize(newSize:CGSize) ->UIImage {
UIGraphicsBeginImageContext(newSize)
self.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage
}
}
self.documentInteractionController = [self setupControllerWithURL:imgurl usingDelegate:self];
self.documentInteractionController=[UIDocumentInteractionController interactionControllerWithURL:imgurl];
self.documentInteractionController.UTI = #"com.instagram.exclusivegram";
Use this code in same sequence . Here documentInteractionController is object of UIDocumentInteractionController.just for your knowledge. you will get instagram only in "open in" window.
Save your image with igo extension instead of ig.
By this you will only get instagram option in your "Open in" Menu.
Or if you want to open directly instagram when you press the button you can pass the direct url of the app and it will lead you to the native instagram app.
Hope it helps you.
Have you checked the size of your image.As it supports image bigger than 612*612 do check the size of your image you are posting
Related
I have a video layer I want to render onto an SCNPlane. It works on the Simulator, but not on the device.
Here's a visual:
Here's the code:
//DISPLAY PLANE
SCNPlane * displayPlane = [SCNPlane planeWithWidth:displayWidth height:displayHeight];
displayPlane.cornerRadius = cornerRadius;
SCNNode * displayNode = [SCNNode nodeWithGeometry:displayPlane];
[scene.rootNode addChildNode:displayNode];
//apply material
SCNMaterial * displayMaterial = [SCNMaterial material];
displayMaterial.diffuse.contents = [[UIColor greenColor] colorWithAlphaComponent:1.0f];
[displayNode.geometry setMaterials:#[displayMaterial]];
//move to front + position for rim
displayNode.position = SCNVector3Make(0, rimTop - 0.08, /*0.2*/ 1);
//create video item
NSBundle * bundle = [NSBundle mainBundle];
NSString * path = [bundle pathForResource:#"tv_preview" ofType:#"mp4"];
NSURL * url = [NSURL fileURLWithPath:path];
AVAsset * asset = [AVAsset assetWithURL:url];
AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];
queue = [AVQueuePlayer playerWithPlayerItem:item];
looper = [AVPlayerLooper playerLooperWithPlayer:queue templateItem:item];
queue.muted = true;
layer = [AVPlayerLayer playerLayerWithPlayer:queue];
layer.frame = CGRectMake(0, 0, w, h);
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
displayMaterial.diffuse.contents = layer;
displayMaterial.doubleSided = true;
[queue play];
//[self.view.layer addSublayer:layer];
I can confirm that the actual plane exists (appears as green in the image above if avplayerlayer isn't applied to it) - first image above. If the video layer is added directly to the parent view layer (bottom line above) it runs fine - final image above. I thought it might be file system issue, but then I imagine (?) the video wouldn't play in the final image.
EDIT: setting queue (AVPlayer) directly works on Simulator, albeit ugly as hell, and crashes on Device, with following error log:
Error: Could not get pixel buffer (CVPixelBufferRef)
validateFunctionArguments:3797: failed assertion `Fragment Function(commonprofile_frag): incorrect type of texture (MTLTextureType2D) bound at texture binding at index 4 (expect MTLTextureTypeCube) for u_radianceTexture[0].'
I think that my solution will suit you - the only thing is that small changes will be required here:
#import <SceneKit/SceneKit.h>
#import <AVKit/AVKit.h>
#import <SpriteKit/SpriteKit.h>
#interface ViewController: UIViewController
#end
It works for simulator (in Xcode 13.2.1) and for device (I run it on iPhone X with iOS 15.3). I used 640x360 H.265 video. The only problem here – a video looping is stuttering...
#import "ViewController.h"
#implementation ViewController
AVQueuePlayer *queue;
AVPlayerLooper *looper;
SKVideoNode *videoNode;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
SCNView *sceneView = (SCNView *)self.view;
sceneView.backgroundColor = [UIColor blackColor];
sceneView.autoenablesDefaultLighting = YES;
sceneView.allowsCameraControl = YES;
sceneView.playing = YES;
sceneView.loops = YES;
SCNScene *scene = [SCNScene scene];
sceneView.scene = scene;
// Display
SCNPlane *displayPlane = [SCNPlane planeWithWidth:1.6 height:0.9];
SCNNode *displayNode = [SCNNode nodeWithGeometry:displayPlane];
SCNMaterial *displayMaterial = [SCNMaterial material];
displayMaterial.lightingModelName = SCNLightingModelConstant;
displayMaterial.doubleSided = YES;
// Video
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"art.scnassets/hevc"
ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:path];
AVAsset *asset = [AVAsset assetWithURL:url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
queue = [AVQueuePlayer playerWithPlayerItem:item];
queue.muted = NO;
looper = [AVPlayerLooper playerLooperWithPlayer:queue templateItem:item];
// SpriteKit video node
videoNode = [SKVideoNode videoNodeWithAVPlayer:queue];
videoNode.zRotation = -M_PI;
videoNode.xScale = -1;
SKScene *skScene = [SKScene sceneWithSize: CGSizeMake(
displayPlane.width * 1000,
displayPlane.height * 1000)];
videoNode.position = CGPointMake(skScene.size.width / 2,
skScene.size.height / 2);
videoNode.size = skScene.size;
[videoNode play];
[skScene addChild:videoNode];
displayMaterial.diffuse.contents = skScene;
[displayNode.geometry setMaterials:#[displayMaterial]];
[scene.rootNode addChildNode:displayNode];
}
#end
I am new to Xcode (using 4.3) and am not sure how to save an image to the device's camera roll. All that I have done so far is set up an IBAction for the button to save the image. What library method or function can I use to save an image to the user's camera roll?
You use the UIImageWriteToSavedPhotosAlbum() function.
//Let's say the image you want to save is in a UIImage called "imageToBeSaved"
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil);
Edit:
//ViewController.m
- (IBAction)onClickSavePhoto:(id)sender{
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil);
}
Here's an answer for iOS8+ using the Photos framework.
Objective-C:
#import <Photos/Photos.h>
UIImage *snapshot = self.myImageView.image;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:snapshot];
changeRequest.creationDate = [NSDate date];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"successfully saved");
}
else {
NSLog(#"error saving to photos: %#", error);
}
}];
Swift:
// Swift 4.0
import Photos
let snapshot: UIImage = someImage
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAsset(from: snapshot)
}, completionHandler: { success, error in
if success {
// Saved successfully!
}
else if let error = error {
// Save photo failed with error
}
else {
// Save photo failed with no error
}
})
Here's a link to the Apple documentation.
Don't forget to add the appropriate key/value to your info.plist to request permission to access the photo library:
<key>NSCameraUsageDescription</key>
<string>Enable camera access to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Enable photo library access to select a photo from your library.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Enable photo library access to save images to your photo library directly from the app.</string>
For reference, you can save videos in a similar manner:
UISaveVideoAtPathToSavedPhotosAlbum(videoPath, nil, nil, nil);
You might want to save a video to upload to Instagram, for example:
// Save video to camera roll; we can share to Instagram from there.
-(void)didTapShareToInstagram:(id)sender {
UISaveVideoAtPathToSavedPhotosAlbum(self.videoPath, self, #selector(video:didFinishSavingWithError:contextInfo:), (void*)CFBridgingRetain(#{#"caption" : caption}));
}
- (void) video: (NSString *) videoPath
didFinishSavingWithError: (NSError *) error
contextInfo: (void *) contextInfoPtr {
NSDictionary *contextInfo = CFBridgingRelease(contextInfoPtr);
NSString *caption = contextInfo[#"caption"];
NSString *escapedString = [videoPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; // urlencodedString
NSString *escapedCaption = [caption stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; // urlencodedString
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:#"instagram://library?AssetPath=%#&InstagramCaption=%#", escapedString, escapedCaption]];
[[UIApplication sharedApplication] openURL:instagramURL];
}
Save the image in photo library in Swift 4
Add "Privacy - Photo Library Additions Usage Description" in info.plist
Then use following code to save image
UIImageWriteToSavedPhotosAlbum(imageView.image!, nil, nil, nil)
Use asImage() to get unique content to save to the camera roll.
If you use asImage() you can save a variety of fun things to the camera roll with just a few lines of code! This can be very powerful if the object has some transparency already incorporated.
asImage() works with UITextView, WKWebView, UIImageView, UIButton, UISlider, UITableView to name some objects (but they may need to be visible when you get the image (having a non zero alpha)). I even use it to capture tiling, but that's loaded into a UIImageView already in my design. I suspect asImage() may work with many more object types too, but I only tried the ones I mentioned.
If it's a UITextView, and you set the background color to .clear then the text gets saved with a transparent background. If your text contains emoji or Memoji, you can now get those images into the camera roll, or into UIImageViews internal to your app. Having Memoji/Emoji with a transparent background in your camera roll where they can be used in any variety of applications is powerful.
Other objects may have some transparency if you crop a photo image to a circle, or set the corner radius to clip off the corners.
Note in my code, pointerToTextObjectSelected is a UITextView
var pointerToTextObjectSelected = UITextView()
// above populated elsewhere
let thisObject = pointerToTextObjectSelected.asImage()
let imageData = thisObject.pngData()
let imageToSave = UIImage(data: imageData!)
UIImageWriteToSavedPhotosAlbum(imageToSave!, nil, nil, nil)
// You will need this extension :
extension UIView {
// Using a function since `var image` might conflict with an existing variable
// (like on `UIImageView`)
func asImage() -> UIImage {
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
} else {
UIGraphicsBeginImageContext(self.frame.size)
self.layer.render(in:UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIImage(cgImage: image!.cgImage!)
}
}
}
In my iPhone app, I am using the iPhone's camera to take a photo and save it do disk (the application's documents folder). This is how i save it:
[UIImageJPEGRepresentation(photoTaken, 0.0) writeToFile:jpegPath atomically:YES];
Using the most compression, I figured reading the image from disk would be quick. But its not! I use the image as the background image for a button in one of my views. I load it like this:
[self.frontButton setBackgroundImage:[UIImage imageWithContentsOfFile:frontPath] forState:UIControlStateNormal];
When I navigate to the view with this button, it is slow and choppy. How do I fix this?
+imageWithContentsOfFile: is synchronous, so the UI on your main thread is being blocked by the image loading from disk operation and causing the choppiness. The solution is to use a method that loads the file asynchronously from disk. You could also do this in a background thread. This can be done easily by wrapping the +imageWithContentsOfFile: in dispatch_async(), then a nested dispatch_async() on the main queue that wraps -setBackgroundImage: since UIKit methods need to be run on the main thread. If you want the image to appear immediately after the view loads, you'll need to pre-cache the image from disk so it's in-memory immediately when the view appears.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:frontPath];
dispatch_async(dispatch_get_main_queue(), ^{
[self.frontButton setBackgroundImage:image forState:UIControlStateNormal];
});
});
As an aside, if the button image happens a gradient, consider using the following properties to ensure the image file loaded from disk is tiny:
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
or (deprecated, only use if you need to support iOS 4.x):
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight
This is the faster way I know. You'll need to import #import <ImageIO/ImageIO.h>
I use this code to download and compress images during a scroll, inside a scrollview and you barely notice the delay.
CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)mutableData, NULL);
CFDictionaryRef options = (CFDictionaryRef)[[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent, (id)[NSNumber numberWithDouble:200.0], (id)kCGImageSourceThumbnailMaxPixelSize, nil];
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
UIImage *image = [[UIImage alloc] initWithCGImage:thumbnail];
// Cache
NSString *fileName = #"fileName.jpg";
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:#"thumbnail"];
path = [path stringByAppendingPathComponent:fileName];
if ([UIImagePNGRepresentation(image) writeToFile:path atomically:YES]) {
// Success
}
I face a very similar issue where I had to load hundreds of images from the directory. My performance was quite slow if I used UIImage(contentsOfFile:) method. The below method increased my performance to 70 %.
class ImageThumbnailGenerator: ThumbnailGenerator {
private let url: URL
init(url: URL) {
self.url = url
}
func generate(size: CGSize) -> UIImage? {
guard let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil) else {
return nil
}
let options: [NSString: Any] = [
kCGImageSourceThumbnailMaxPixelSize: Double(max(size.width, size.height) * UIScreen.main.scale),
kCGImageSourceCreateThumbnailFromImageIfAbsent: true
]
return CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as NSDictionary).flatMap { UIImage(cgImage: $0) }
}
}
I'm new to iphone. In my small application, how to get image path from photo library. I use this following code to getting images and placed in imageview.
-(IBAction) selectimage
{
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentModalViewController:picker animated:YES];
[picker release];
}
-(void) imagePickerController:(UIImagePickerController *)UIPicker didFinishPickingMediaWithInfo:(NSDictionary *) info
{
[UIPicker dismissModalViewControllerAnimated:YES];
imageview.image=[info objectForKey:"UIImagePickerControllerOriginalImage"];
NSLog("Image Path=%#",imageview.image);
}
Its succefully placed to Imageview. But i cant get its imagepath. I'm using nslog("%#",imageview.image); it shows "Image Path=" in console.
How can i get its path and how to retrieve photos from photo library. Any body help me. Thanks in advance.
UIImagePickerControllerOriginalImage returns only the image's data, with no reference to its local storage. I haven't used it myself but I guess what you are looking for is
NSURL* localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerReferenceURL];
At least, it's the only way I know of to retrieve any URL.
To retrieve the image, have a look at this question. But also keep in mind, that you already have the image retrieved with
UIImage* image=(UIImage*)[info objectForKey:#"UIImagePickerControllerOriginalImage"];
so ask yourself if you really need this.
Swift 3.0, You can get imageData from referenceURL by following way
let url = URL(string: "assets-library://asset/asset.JPG?id=1000000007&ext=JPG")
let asset = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil)
guard let result = asset.firstObject else {
return nil
}
let imageManager = PHImageManager.default()
var imageData: Data? = nil
imageManager.requestImageData(for: result, options: nil, resultHandler: { (data, string, orientation, dict) in
imageData = data
})
I have the following code to get the UIImage from MPMediaItemPropertyArtWork to display the coverArt in my view. I get a non-NULL artwork from the mediaItem, however, when I try to extract the UIImage from the artwork, it returns NULL and I don't see anything in my UIImageView. Any help will be greatly appreciated.
CGSize artworkSize = CGSizeMake(30, 30);
UIImage *artworkImage;
MPMediaItemArtwork *artwork = [song valueForProperty: MPMediaItemPropertyArtwork];
if (artwork) {
NSLog(#"artwork available");
artworkImage = [artwork imageWithSize:artworkSize];
} else {
NSLog(#"artwork not available");
artworkImage = [UIImage imageNamed:#"EmptyAlbum.png"];
}
NSLog(#"artworkImage = %#", artworkImage);
coverArtView.image = artworkImage;
Try with this - have use a UItableview to display album details.
declare MPMediaItemCollection *userMediaCollection;
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {
[self setUserMediaCollection:mediaItemCollection];
[self dismissModalViewControllerAnimated:YES];
}
MPMediaItem *mItem = (MPMediaItem *)[userMediaCollection.items objectAtIndex:indexPath.row];
MPMediaItemArtwork *artWork = [mItem valueForProperty:MPMediaItemPropertyArtwork];
cell.imageView.image = [artWork imageWithSize:CGSizeMake(30, 30)];
where userMediaCollection is your MPMediaItemCollection
try this... it is work.
CGSize artworkSize = CGSizeMake(30, 30);
UIImage *artworkImage;
MPMediaItemArtwork *artwork = [song valueForProperty: MPMediaItemPropertyArtwork];
artworkImage = [artwork imageWithSize:artworkSize];
if (artworkImage == nil) {
NSLog(#"artwork not available");
artworkImage = [UIImage imageNamed:#"EmptyAlbum.png"];
}
coverArtView.image = artworkImage;
I know this question is a bit old by now, but for anyone finding this, this might help:
I was scratching my head over this for a few hours, because getting the artwork was working in one view controller in my app but not in my UITableViewController. My code looked exactly the same in both instances (and very similar to yours) except for ONE thing:
let albumArtImage = albumArt.imageWithSize(cell.imageView.bounds.size)
the SIZE! (Sorry for writing this in Swift, but you get the idea). It sounds stupid, but the MPMediaItemArtwork refused to give me a small image. I literally just changed it to a bigger size, like so:
let albumArtImage = albumArt.imageWithSize(CGSize(width: 150, height: 150))
and it worked. You can resize the UIImage to fit your needs later anyway.
If anyone finds this and this (stupid) solution works, please let me know via a reply or something.
How do you initialize you MPMusicPlayerController? It should be:
MPMusicPlayerController *player = [MPMusicPlayerController iPodMusicPlayer];
See answer: https://stackoverflow.com/a/26463261/883413
Appears to be an iOS bug. If the image returned is nil, try using the artwork size instead.
UIImage *image = [artwork imageWithSize:size];
if (image == nil) {
image = [artwork imageWithSize:artwork.bounds.size];
}