I am trying to get the size of an image after it is downloaded using setImageFromURL:
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[UIImageView setDefaultEngine:appDelegate.imageCache];
[img setImageFromURL:[NSURL URLWithString:#"http://testurl.com/testimg.jpg"]];
//img.frame = CGRectMake (0, 0, img.image.size.width, img.image.size.height);
[self.view addSubview:img];
I'm using MKNetworkKit -- is there a way to add a completion handler to the setImageFromURL method?
You can apply your own completion block
Few comments, please use Grand Central Dispatch to improve code efficiency and multi-core utilization for this kind of situations.
Example:
- (void) setImageFromUrl:(NSString*)urlString {
[self setImageFromUrl:urlString completion:NULL];
}
- (void) setImageFromUrl:(NSString*)urlString
completion:(void (^)(void))completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"Starting: %#", urlString);
UIImage *avatarImage = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *responseData = [NSData dataWithContentsOfURL:url];
avatarImage = [UIImage imageWithData:responseData];
NSLog(#"Finishing: %#", urlString);
if (avatarImage) {
dispatch_async(dispatch_get_main_queue(), ^{
self.image = avatarImage;
//Assign the image to ur ImageView.
//get the image frame from ur ImageView.frame
});
dispatch_async(dispatch_get_main_queue(), completion);
}
else {
NSLog(#"-- impossible download: %#", urlString);
}
});
}
For more details , please visit iOS GCD magic
I was able to do it by adding this line:
self.frame = CGRectMake(0, 0, fetchedImage.size.width, fetchedImage.size.height);
to UIImageView+MKNetworkKitAdditions.m:
if(imageCacheEngine) {
self.imageFetchOperation = [imageCacheEngine imageAtURL:url
size:self.frame.size
completionHandler:^(UIImage *fetchedImage, NSURL *url, BOOL isInCache) {
self.frame = CGRectMake(0, 0, fetchedImage.size.width, fetchedImage.size.height);
[UIView transitionWithView:self.superview
duration:isInCache?kFromCacheAnimationDuration:kFreshLoadAnimationDuration
options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.image = fetchedImage;
} completion:nil];
//[[NSNotificationCenter defaultCenter] postNotificationName:KW_IMAGE_LOADED object:nil];
} errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
DLog(#"%#", error);
}];
} else {
DLog(#"No default engine found and imageCacheEngine parameter is null")
}
Related
I have 3 images. I load one by one to camera overlay image. Then i need to take snapshot. But when i click button it take snapshot of particular image. When i put imageName.png in captureStillImageWithOverlay it take snapshot of that image only, it won't taking other images when present in overlay
Button click code:
- (void)ButtonPressed {
[[self captureManager] captureStillImageWithOverlay:[UIImage imageNamed:#"img2.png"]];
}
Load images:
-(void)loadNextPage:(int)index
{
int countFlag=0;
for(int i=index*4;i<(index+1)*4;i++)
{
UIButton *imageView=[[UIButton alloc]initWithFrame:CGRectMake((320*index)+countFlag*80+ 2, 5, 75, 75)];
imageView.tag=i+1;
[imageView addTarget:self action:#selector(imageViewClicked:) forControlEvents:UIControlEventTouchUpInside];
[imageView.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[imageView.layer setBorderWidth:1.0f];
switch ((i+1)%5) {
case 0:
[imageView setImage:[UIImage imageNamed:#"img1.png"] forState:UIControlStateNormal];
break;
case 1:
[imageView setImage:[UIImage imageNamed:#"img2.png"] forState:UIControlStateNormal];
break;
case 2:
[imageView setImage:[UIImage imageNamed:#"img3.png"] forState:UIControlStateNormal];
break;
}
[myScrollView addSubview:imageView];
[imageView release];
countFlag++;
}
}
Capture overlay image:
- (void)captureStillImageWithOverlay:(UIImage*)overlay
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
NSLog(#"about to request a capture from: %#", [self stillImageOutput]);
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments) {
NSLog(#"attachements: %#", exifAttachments);
} else {
NSLog(#"no attachments");
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
CGSize imageSize = [image size];
CGSize overlaySize = [overlay size];
UIGraphicsBeginImageContext(imageSize);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
CGFloat xScaleFactor = imageSize.width / 320;
CGFloat yScaleFactor = imageSize.height / 480;
[overlay drawInRect:CGRectMake(30 * xScaleFactor, 100 * yScaleFactor, overlaySize.width * xScaleFactor, overlaySize.height * yScaleFactor)]; // rect used in AROverlayViewController was (30,100,260,200)
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
[self setStillImage:combinedImage];
UIGraphicsEndImageContext();
[image release];
[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];
}];
}
I take the reference from this url [http://www.musicalgeometry.com/?p=1681]
An overlay is just for presentation in the camera picker.
You also need to combine these images in your final UIImage (JPEG or TIFF or whatever) you save to disk.
Other people have had (and have solved) this same problem as you.
EDIT, here is some code that may help you out:
- (void)captureStillImageWithOverlay:(NSArray *) arrayOfImageFiles
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
NSLog(#"about to request a capture from: %#", [self stillImageOutput]);
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments) {
NSLog(#"attachements: %#", exifAttachments);
} else {
NSLog(#"no attachments");
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
CGSize imageSize = [image size];
UIGraphicsBeginImageContext(imageSize);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
CGFloat xScaleFactor = imageSize.width / 320;
CGFloat yScaleFactor = imageSize.height / 480;
for(NSString * imageFileName in arrayOfImageFiles)
{
// images named #"img1" or #"img1.png" should work
UIImage * overlay = [UIImage imageNamed: imageFileName];
if(overlay)
{
CGSize overlaySize = [overlay size];
[overlay drawInRect:CGRectMake(30 * xScaleFactor, 100 * yScaleFactor, overlaySize.width * xScaleFactor, overlaySize.height * yScaleFactor)]; // rect used in AROverlayViewController was (30,100,260,200)
} else {
NSLog( #"could not find an image named %#", imageFileName);
}
}
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
[self setStillImage:combinedImage];
UIGraphicsEndImageContext();
[image release];
[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];
}];
}
I'm using SDWebImage (2.7.3 framework) and I receive corrupt images, I can't understand exactly the problem. If is the code (memory...)
(notes:
I get the same error using the SDWebImage project instead of the framework.
I'm implementing "autorelease" and other kinds of memory management.
This problem arises on devices (iPad), but not in the simulator)
__block CALayer *layerCover = [[CALayer alloc] init];
layerCover.frame = CGRectMake(3, 3, COVER_WIDTH_IPAD_SMALL, COVER_HEIGHT_IPAD_SMALL);
[btn.layer addSublayer:layerCover];
[_scroll addSubview:btn];
[btn release];
//request or load Vods Images
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#M", vod.cover]]
delegate:self options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached) {
if (image) {
layerCover.contents = (id)image.CGImage;
}
[layerCover release];
} failure:^(NSError *error) {
[layerCover release];
}];
//another kind
UIImage * imageTv = [UIImage imageNamed:#"bgDefaultTvImage.png"];
UIImageView * bgTvImage = [[UIImageView alloc] initWithFrame:CGRectMake(startX, 20, imageTv.size.width, imageTv.size.height)];
[bgTvImage setImage:imageTv];
CGFloat sizeWithIcon = imageTv.size.width;
CGFloat sizeHeightIcon = imageTv.size.height;
__block UIImageView * bgImageicon = [[UIImageView alloc] initWithFrame:CGRectMake((bgTvImage.frame.size.width-sizeWithIcon)/2,
(bgTvImage.frame.size.height-sizeHeightIcon)/2,
sizeWithIcon,
sizeHeightIcon)];
bgImageicon.contentMode = UIViewContentModeScaleAspectFit;
[bgTvImage addSubview:bgImageicon];
[tvTopView addSubview:bgTvImage];
/*
* Request ProgramImage
*/
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#&width=300",program.ProgramImage.imageURL]]
delegate:self options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached) {
if (image) {
iconCanal = image;
[bgImageicon setImage:iconCanal];
}
[bgImageicon release];
}failure:^(NSError *error) {
[bgImageicon release];
}];
Xcode logs:
<Error>: ImageIO: JPEG Corrupt JPEG data: bad Huffman code
<Error>: ImageIO: JPEG Corrupt JPEG data: premature end of data segment
It seems to be the problem of SDWebImageProgressiveDownload flag. Try to disable it, for example like this:
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#&width=300",program.ProgramImage.imageURL]]
delegate:self options:0 success:^(UIImage *image, BOOL cached) {
if (image) {
iconCanal = image;
[bgImageicon setImage:iconCanal];
}
[bgImageicon release];
}failure:^(NSError *error) {
[bgImageicon release];
}];
Hi i've got a problem with display an image on my scrollView.
At first i create new UIImageView with asset url:
-(void) findLargeImage:(NSNumber*) arrayIndex
{
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep;
if([myasset defaultRepresentation] == nil) {
return;
} else {
rep = [myasset defaultRepresentation];
}
CGImageRef iref = [rep fullResolutionImage];
itemToAdd = [[UIImageView alloc] initWithFrame:CGRectMake([arrayIndex intValue]*320, 0, 320, 320)];
itemToAdd.image = [UIImage imageWithCGImage:iref];
[self.scrollView addSubview:itemToAdd];
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Cant get image - %#",[myerror localizedDescription]);
};
NSURL *asseturl = [NSURL URLWithString:[self.photoPath objectAtIndex:[arrayIndex intValue] ]];
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
}
Where itemToAdd is a UIImageView define in interface:
__block UIImageView *itemToAdd;
And scrollView define as a property:
#property (nonatomic, strong) __block UIScrollView *scrollView;
Then in my viewWillAppear i do this:
- (void) viewWillAppear:(BOOL)animated {
self.scrollView.delegate = self;
[self findLargeImage:self.actualPhotoIndex];
[self.view addSubview:self.scrollView];
}
But image doesnt appear, should i refresh self.view after add image to scrollView, or should do something else?
ALAssetsLibrary block will execute in separate thread. So I suggest to do the UI related stuffs in main thread.
To do this either use dispatch_sync(dispatch_get_main_queue() or performSelectorOnMainThread
Some Important Notes:
Use AlAsset aspectRatioThumbnail instead of fullResolutionImage for high performance
Example:
CGImageRef iref = [myasset aspectRatioThumbnail];
itemToAdd.image = [UIImage imageWithCGImage:iref];
Example:
-(void) findLargeImage:(NSNumber*) arrayIndex
{
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
CGImageRef iref = [myasset aspectRatioThumbnail];
dispatch_sync(dispatch_get_main_queue(), ^{
itemToAdd = [[UIImageView alloc] initWithFrame:CGRectMake([arrayIndex intValue]*320, 0, 320, 320)];
itemToAdd.image = [UIImage imageWithCGImage:iref];
[self.scrollView addSubview:itemToAdd];
});//end block
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Cant get image - %#",[myerror localizedDescription]);
};
NSURL *asseturl = [NSURL URLWithString:[self.photoPath objectAtIndex:[arrayIndex intValue] ]];
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
}
Also change the order of viewWillAppear()
- (void) viewWillAppear:(BOOL)animated {
self.scrollView.delegate = self;
[self.view addSubview:self.scrollView];
[self findLargeImage:self.actualPhotoIndex];
}
You are manipulating the view from another thread.
You must use the main thread for manipulating the view.
Add image to scrollView using:
dispatch_async(dispatch_get_main_queue(), ^{
[self.scrollView addSubview:itemToAdd];
}
or using:
[self.scrollView performSelectorOnMainThread:#selector(addSubview:) withObject:itemToAdd waitUntilDone:NO];
Please refer:
NSObject Class Reference
GCD
I am streamlining the AVCamDemo project so that I can experiment with capturing only still images.
Below is the new code for captureStillImage() method:
- (void) captureStillImage
{
AVCaptureConnection *stillImageConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
if ([stillImageConnection isVideoOrientationSupported]) {
[stillImageConnection setVideoOrientation:orientation];
}
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:stillImageConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
NSLog(#"In the completionHandler block");
if (imageDataSampleBuffer != NULL) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[self writeImageFile:image];
[image release];
}
if ([[self delegate] respondsToSelector:#selector(captureManagerStillImageCaptured:)]) {
[[self delegate] captureManagerStillImageCaptured:self];
}
}];
NSLog(#"exiting....");
}
In my testing, I have found that sometimes, the NSLog statement in the block is not executed....and therefore the stillImage file does not get saved.
Am I running into timing issues? If so, how do I address them?
Thanks, and regards.
Sam.
I have implemented a small method that imports an picture on the
iPhone screen, but the picture is a little bit to big for the screen.
This is the Method:
- (void)ladeImage {
id path = #"http://172.23.1.63:8080/RestfulJava/pics";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
[self.view addSubview:imgView];
}
But is there any method to scale the picture on the iPhone screen?
Edit1:
Ok thank for your helping, but this method doesn't work, when I switch the iPhone to landscape, her is the code with your tipp:
- (void)ladeImage {
id path = #"http://172.23.1.63:8080/RestfulJava/pics";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
[imgView setContentMode:UIViewContentModeScaleToFill];
imgView.frame = self.view.frame;
[self.view addSubview:imgView];
}
Edit2:
look this is my class:
- (void)viewDidLoad {
[self ladeImage];
[super viewDidLoad];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if(toOrientation == UIInterfaceOrientationPortrait || toOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
ImgMainPhoto.frame = CGRectMake(0, 0, 320, 480);
[self PortraitMode];
} else if((toOrientation == UIInterfaceOrientationLandscapeLeft ) || (toOrientation == UIInterfaceOrientationLandscapeRight)) {
ImgMainPhoto.frame = CGRectMake(0, 0, 480, 320);
[self LendscapreMode];
}
}
- (void)ladeImage {
id path = #"http://172.23.1.63:8080/RestfulJava/pics";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
imgView.frame = self.view.frame;
imgView.contentMode = UIViewContentModeScaleToFill;
[self.view addSubview:imgView];
}
you should insert following code before inserting imageview to the view.
[imgView setContentMode:UIViewContentModeScaleToFill]
Also you can set/change from ScaleToFill to AspectFill or as you needed.
and problem will be soved.
Just change the frame to the screen size, i.e. imgView.frame = self.view.frame
look this is my class:
- (void)viewDidLoad {
[self ladeImage];
[super viewDidLoad];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if(toOrientation == UIInterfaceOrientationPortrait || toOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
ImgMainPhoto.frame = CGRectMake(0, 0, 320, 480);
[self PortraitMode];
} else if((toOrientation == UIInterfaceOrientationLandscapeLeft ) || (toOrientation == UIInterfaceOrientationLandscapeRight)) {
ImgMainPhoto.frame = CGRectMake(0, 0, 480, 320);
[self LendscapreMode];
}
}
- (void)ladeImage {
id path = #"http://172.23.1.63:8080/RestfulJava/pics";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
imgView.frame = self.view.frame;
imgView.contentMode = UIViewContentModeScaleToFill;
[self.view addSubview:imgView];
}