Is there a way to check only if two UIimages are different. Right now I am using following method which works fine but it takes time. Is there any alternative? It should return false if there is any pixel of mismatched area.
if ([UIImagePNGRepresentation(lastImage)
isEqualToData:UIImagePNGRepresentation(newImage)] )
{
return true;
}
else
{
return false;
}
if you use TIFF there's no image conversion done. Takes very little time.
NSData *data = [image TIFFRepresentation];
NSData *data2 = [image2 TIFFRepresentation];
if ([data isEqualToData:data2]) {
// Do Stuff
}
Related
I have 2 main small image buttons say aBtn & bBtn. When i click aBtn / bBtn i Generate 6 image url as default checking the condition that the images are not nil. In the 6 images if some images are empty then i avoid that empty image alone & set the frame accordingly. When i click from aBtn to bBtn, i have the time delay. It is due to checking the 6 url images generate without nil/empty image each time & by setting the frame position accordingly.
This is the code i used to display the images & check the condition from the 6 url images data is not nil if something say 3rd url image is nil it will be avoided. How to overcome the delay to display the images?
NSMutableString *strUrl;
int i;
int j=7;
int k=0;
xorigin=350;
int cou=1;
for( i=1;i<j;i++){
strUrl=[[NSMutableString alloc]init];
UIImageView *imageView= [[UIImageView alloc]init];
[strUrl appendFormat:#"http://commondatastorage.googleapis.com/images2.solestruck.com/%#%#%#%#%#%#%#)-01060%d.jpg",
[[[[shoeDetailDict objectForKey:#"vendorName"] lowercaseString] lowercaseString] stringByReplacingOccurrencesOfString:#" " withString:#"-"],#"-shoes/",[[shoeDetailDict objectForKey:#"vendorName"] stringByReplacingOccurrencesOfString:#" " withString:#"-"],#"-shoes-",[[shoeDetailDict objectForKey:#"productName"] stringByReplacingOccurrencesOfString:#" " withString:#"-"],#"-(",[[prdcolorimgArray objectAtIndex:tagedColor] stringByReplacingOccurrencesOfString:#" " withString:#"-"],i];
NSURL *imageUrl=[[NSURL alloc]initWithString:strUrl];
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:strUrl] options:NSDataReadingUncached error:&error];
NSLog(#"imageurl colors : %#",strUrl);
if(i==4){
imageView.frame =CGRectMake(25, 0, (self.view.frame.size.width*80)/100,(self.view.frame.size.height*40)/100);
[imageView setImageWithURL:imageUrl];
}
else{
if(data != nil ){
cou++;
imageView.frame =CGRectMake(xorigin, 0, (self.view.frame.size.width*80)/100,(self.view.frame.size.height*40)/100);
[imageView setImageWithURL:imageUrl];
xorigin=xorigin+320;
}
}
imageView.backgroundColor=[UIColor whiteColor];
[productScroll addSubview:imageView];
productScroll.contentSize = CGSizeMake((self.view.frame.size.width)*cou, (self.view.frame.size.height*40)/100);
productScroll.contentOffset=CGPointMake(0, 0);
k++;
}
You are using dataWithContentsOfURL: that load information synchronously.
Try to load all images first and than put them on the scroll view.
Try to use this code:
- (void) prepareImages {
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSMutableArray * imagesArray = [NSMutableArray array];
// Load all images here
[self imagesLoaded:imagesArray]
});
}
- (void) imagesLoaded:(NSArray*) images {
dispatch_async(dispatch_get_main_queue(), ^{
//Display images here
});
}
I am downloading multiple images from below code and saving to the DB. But for some images I am getting below error.
Error: ImageIO: PNG invalid distance too far back
Error: ImageIO: PNG incorrect data check
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *imgStr = [dict objectForKey:#"image"];
imgStr = [imgStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgStr]];
UIImage *image = [UIImage imageWithData:imgData];
dispatch_sync(dispatch_get_main_queue(), ^{
mYImageView.image = image;
});
});
How to check stored image is valid or not, so I can download image again?
For PNG images, check their first two bytes and last two bytes. Below is the method, hope it helps.
Thanks. :)
- (BOOL)isImageValid:(NSData *)data
{
BOOL val = YES;
if ([data length] < 4)
val = NO;
const char * bytes = (const char *)[data bytes];
if (bytes[0] != 0x89 || bytes[1] != 0x50)
val = NO;
if (bytes[[data length] - 2] != 0x60 ||
bytes[[data length] - 1] != 0x82)
val = NO;
return val;
}
The accepted answer by swati sharma works great. Here’s a Swift extension for anyone looking to do the same in Swift:
extension Data
{
/// Returns whether or not the data is for a valid PNG file.
var isValidPNG: Bool
{
guard self.count > 4 else { return false }
return self[0] == 0x89 &&
self[1] == 0x50 &&
self[self.count - 2] == 0x60 &&
self[self.count - 1] == 0x82
}
}
I am working with NSCache in iOS i have following code in .h file for cache:
NSCache *_cache;
I am adding the image which are downloading from the url to the cache in .m:
-(void)cacheFromURL:(NSURL*)url
{
[_cache setCountLimit:50];
UIImage* newImage = [_cache objectForKey:url.description];
if( !newImage )
{
NSError *err = nil;
if(url!=Nil)
{
newImage=[UIImage imageWithData:[NSData dataWithContentsOfURL:url options:0 error:&err]];
}
if( newImage )
{
[_cache setValue:newImage forKey:url.description];
}
else
{
NSLog( #"UIImageView:LoadImage Failed: %#", err );
}
if(_cache==Nil)
{
NSLog(#"nil");
}
else
{
NSLog(#"cache is not nil");
}
}
}
But i am getting the nil cache every time . where i can see the downloading process in log .
why am i getting null cache?
You need to create/initialize the NSCache object before you can add and object to it. Also you need to add object with the setObject:forKey:
You have to initialize your NSCache object first:
_cache = [[NSCache alloc] init];
I want to know that the image file size in IPhone PhotoAlbum which selected by UIImagePickerController.
I've tried this code with 1,571,299 byte jpeg image.
UIIamge *selectedImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *imageData;
if ( /* PNG IMAGE */ )
imageData = UIImagePNGReprensentation(selectedImage);
else
imageData = UIImageJPEGReprensentation(selectedImage);
NSUInteger fileLength = [imageData length];
NSLog(#"file length : [%u]", fileLength);
But when I run the code, it print 362788 byte.
Is there anybody who know this?
If you have code like this to take a picture:
UIImagePickerController *controller = [[[UIImagePickerController alloc] init] autorelease];
controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
controller.delegate = self;
[self presentModalViewController:controller animated:YES];
Then you can retrieve a file size of the picked image in the following way:
NSURL *assetURL = [info objectForKey:#"UIImagePickerControllerReferenceURL"];
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
[library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
NSLog(#"Size: %lld", asset.defaultRepresentation.size);
} failureBlock:nil];
If the source type is UIImagePickerControllerSourceTypeCamera, you must save the in-memory image to disk before retrieving its file size.
As some commenters have said, even if we assume the methodology is correct you are reprocessing the image anyway so the byte sizes will not match. I use the following method for JPG images, ymmv for PNG:
+ (NSInteger)bytesInImage:(UIImage *)image {
CGImageRef imageRef = [image CGImage];
return CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);
}
The above, as a commenter noted, does return the uncompressed size however.
here is in Swift 4
extension UIImage {
var memorySize: Int {
guard let imageRef = self.cgImage else { return 0 }
return imageRef.bytesPerRow * imageRef.height
}
}
The user can choose whether he wants to use an existing image or take a new one for use as the background.
Everything works as far as the FirstViewController is concerned. Sadly the image is no longer set as the background, when the SecondViewController is displayed.
How do I enable the use of the image as background for the SecondViewController?
I used this piece of code (in the SecondViewController):
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
int bla = [prefs integerForKey:#"background_key"];
if (bla == 1) {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"1.mac.jpg"]];
} else if (bla == 2) {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"black.jpg"]];
} else if (bla == 3) {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"pinn.png"]];
} else if (bla == 4) {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"MyImage.png"]];
}
I tried to save the chosen image as "MyImage.png" but it looks as though it did not work. The background is black instead of the image selected.
I used this code (from the 1stViewController) to save the chosen picture as "MyImage.png":
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)anInfo {
//UIImage *selectedImage;
NSURL *mediaUrl;
mediaUrl = (NSURL *)[anInfo valueForKey:UIImagePickerControllerMediaURL];
if (mediaUrl == nil)
{
selectedImage = (UIImage *) [anInfo valueForKey:UIImagePickerControllerEditedImage];
if (selectedImage == nil)
{
selectedImage = (UIImage *) [anInfo valueForKey:UIImagePickerControllerOriginalImage];
NSLog(#"Original image picked.");
}
else
{
NSLog(#"Edited image picked.");
}
}
[picker dismissModalViewControllerAnimated:YES];
if (selectedImage != nil)
{
self.view.backgroundColor = [UIColor colorWithPatternImage:selectedImage];
}
// Get the image from the result
UIImage* ownImage = [anInfo valueForKey:UIImagePickerControllerOriginalImage];
// Get the data for the image as a PNG
NSData* imageData = UIImagePNGRepresentation(ownImage);
// Give a name to the file
NSString* imageName = #"MyImage.png";
// Now, we have to find the documents directory so we can save it
// Note that you might want to save it elsewhere, like the cache directory,
// or something similar.
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
// Now we get the full path to the file
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
// and then we write it out
[imageData writeToFile:fullPathToFile atomically:NO];
return;
}
There must be a mistake or logical mistake.
Help would be appreciated!
ImageNamed is generally used to load images that are included as part of the resources of an application.
I suspect you want:
UIImage* image = [UIImage imageWithContentsOfFile:fileNameAndPath];
Try loading the image with similar code to how you save it instead of using +imageNamed:: build the full path and load it from there.
+imageNamed: "looks for an image with the specified name in the application’s main bundle." (UIImage reference), but that's not where you are saving it to. I don't think you can write into the application's bundle, so you won't be able to use +imageNamed: here.