Как resize изображения программно в объективе-c в iphone
У меня есть приложение, где я показываю большие изображения в небольшом пространстве. Изображения довольно большие, но я показываю их только в кадрах 100×100 пикселей. Мое приложение медленно реагирует из-за размера изображений, которые я использую.
Чтобы повысить производительность, как программно resize изображений с помощью Objective-C?
- UISlider для управления AVAudioPlayer
- Можем ли мы пригласить людей использовать наше приложение или отправить запрос друга из приложения через Facebook в iOS 5?
- Как использовать CaptiveNetwork для получения текущего имени точки доступа Wi-Fi
- Воспроизведение звука на iPhone даже в бесшумном режиме
- Как я могу нажать кнопку за прозрачным UIView?
- Как использовать performSelector: withObject: afterDelay: с примитивными типами в cocoa?
- как скрыть навигационную панель, когда я нажимаю навигационный controller?
- UIButton внутри представления с UITapGestureRecognizer
- Как изменить определенный цвет в изображении?
- Перетаскивание UIView внутри UIScrollView
- Запустите NSRunLoop в командной строке программы Cocoa
- Возможно открытие всплывающих ссылок в UIWebView?
- Странная проблема сравнения поплавков в объективе-C
Пожалуйста, найдите следующий код.
- (UIImage *)imageWithImage:(UIImage *)image convertToSize:(CGSize)size { UIGraphicsBeginImageContext(size); [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return destImage; }
Этот код предназначен только для изменения масштаба изображения, а не для изменения размера. Вы должны установить CGSize в качестве ширины и высоты изображения, чтобы изображение не растягивалось и оно располагалось посередине.
- (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size { CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height); CGFloat width = image.size.width * scale; CGFloat height = image.size.height * scale; CGRect imageRect = CGRectMake((size.width - width)/2.0f, (size.height - height)/2.0f, width, height); UIGraphicsBeginImageContextWithOptions(size, NO, 0); [image drawInRect:imageRect]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
Мой любимый способ сделать это – CGImageSourceCreateThumbnailAtIndex
(в среде ImageIO). Имя немного вводит в заблуждение.
Вот fragment кода из недавнего моего приложения.
CGFloat maxw = // whatever; CGFloat maxh = // whatever; CGImageSourceRef src = NULL; if ([imageSource isKindOfClass:[NSURL class]]) src = CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil); else if ([imageSource isKindOfClass:[NSData class]]) src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil); // if at double resolution, double the thumbnail size and use double-resolution image CGFloat scale = 1; if ([[UIScreen mainScreen] scale] > 1.0) { scale = 2; maxw *= 2; maxh *= 2; } // load the image at the desired size NSDictionary* d = @{ (id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue, (id)kCGImageSourceThumbnailMaxPixelSize: @((int)(maxw > maxh ? maxw : maxh)) }; CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d); if (NULL != src) CFRelease(src); UIImage* im = [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp]; if (NULL != imref) CFRelease(imref);
Если вы используете изображение разных размеров и изменяете размер каждый раз, это ухудшит производительность вашего приложения. Решение не изменяет размер, просто используйте кнопку вместо изображения. и просто установите изображение на кнопке, оно будет автоматически изменяться, и вы получите отличную производительность.
Я также менял размер изображений, устанавливая его на ячейку, но мое приложение медленно, поэтому я использовал Button вместо изображения (не изменяя размер изображения, программно кнопка выполняет эту работу), и он работает отлично.
-(UIImage *)scaleImage:(UIImage *)image toSize:. (CGSize)targetSize { //If scaleFactor is not touched, no scaling will occur CGFloat scaleFactor = 1.0; //Deciding which factor to use to scale the image (factor = targetSize / imageSize) if (image.size.width > targetSize.width || image.size.height > targetSize.height || image.size.width == image.size.height) if (!((scaleFactor = (targetSize.width / image.size.width)) > (targetSize.height / image.size.height))) //scale to fit width, or scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.
Так как код отлично работал в iOS 4, для обратной совместимости я добавил проверку на версию ОС и для чего-либо ниже 5.0 старый код будет работать.
- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality { BOOL drawTransposed; CGAffineTransform transform = CGAffineTransformIdentity; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) { // Apprently in iOS 5 the image is already correctly rotated, so we don't need to rotate it manually drawTransposed = NO; } else { switch (self.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: drawTransposed = YES; break; default: drawTransposed = NO; } transform = [self transformForOrientation:newSize]; } return [self resizedImage:newSize transform:transform drawTransposed:drawTransposed interpolationQuality:quality]; }
Вы можете использовать это.
[m_Image.layer setMinificationFilter:kCAFilterTrilinear];
Эта ветка устарела, но я пытаюсь решить эту проблему. Как только изображение масштабируется, оно не отображается хорошо в моем контейнере, даже если я отключил автомат. Самый простой способ разрешить это для отображения в строке таблицы – это рисовать изображение на белом фоне с фиксированным размером.
Вспомогательная функция
+(UIImage*)scaleMaintainAspectRatio:(UIImage*)sourceImage :(float)i_width :(float)i_height { float newHeight = 0.0; float newWidth = 0.0; float oldWidth = sourceImage.size.width; float widthScaleFactor = i_width / oldWidth; float oldHeight = sourceImage.size.height; float heightScaleFactor = i_height / oldHeight; if (heightScaleFactor > widthScaleFactor) { newHeight = oldHeight * widthScaleFactor; newWidth = sourceImage.size.width * widthScaleFactor; } else { newHeight = sourceImage.size.height * heightScaleFactor; newWidth = oldWidth * heightScaleFactor; } // return image in white rect float cxPad = i_width - newWidth; float cyPad = i_height - newHeight; if (cyPad > 0) { cyPad = cyPad / 2.0; } if (cxPad > 0) { cxPad = cxPad / 2.0; } CGSize size = CGSizeMake(i_width, i_height); UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0); [[UIColor whiteColor] setFill]; UIRectFill(CGRectMake(0, 0, size.width, size.height)); [sourceImage drawInRect:CGRectMake((int)cxPad, (int)cyPad, newWidth, newHeight)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; // will return scaled image at actual size, not in white rect // UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)); // [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)]; // UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); // UIGraphicsEndImageContext(); // return newImage; }
Я так назвал это из своего представления таблицы cellForRowAtIndexPath
PFFile *childsPicture = [object objectForKey:@"picture"]; [childsPicture getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) { if (!error) { UIImage *largePicture = [UIImage imageWithData:imageData]; UIImage *scaledPicture = [Utility scaleMaintainAspectRatio:largePicture :70.0 :70.0 ]; PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100]; thumbnailImageView.image = scaledPicture; [self.tableView reloadData]; } }];