Use of imageWithContentsOfFile to reduce image size

Added a cache for height calculation (until chat bubble are moved to autolayout)
Added a cache for images to reduce memory footprint
This commit is contained in:
Christophe Deschamps 2022-02-04 11:38:49 +01:00
parent a9e4c40f92
commit d4d3f95b96
4 changed files with 91 additions and 22 deletions

View file

@ -79,6 +79,7 @@
}
[CallManager.instance stopLinphoneCore];
}
[SwiftUtil resetCachedAsset];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {

View file

@ -30,7 +30,7 @@
#define chatView VIEW(ChatConversationView)
#define FILE_ICON_TAG 0
#define REALIMAGE_TAG 1
#define PHOTO_LIBRARY_FETCH_IMAGE_SIZE CGSizeMake(UIScreen.mainScreen.bounds.size.width * 0.8f,UIScreen.mainScreen.bounds.size.width * 0.8f)
@implementation UIChatBubblePhotoCell {
@ -126,19 +126,30 @@
}
- (void) loadAsset:(PHAsset *) asset {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = TRUE;
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options
resultHandler:^(UIImage *image, NSDictionary * info) {
if (image) {
imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN];
[chatTableView.imagesInChatroom setObject:image forKey:[asset localIdentifier]];
[self loadImageAsset:asset image:image];
}
else {
LOGE(@"Can't read image");
}
}];
UIImage *image = [SwiftUtil getCachedImageWithKey:asset];
if (image) {
imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN];
[chatTableView.imagesInChatroom setObject:image forKey:[asset localIdentifier]];
[self loadImageAsset:asset image:image];
return;
} else {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = FALSE;
options.resizeMode = PHImageRequestOptionsResizeModeNone;
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHOTO_LIBRARY_FETCH_IMAGE_SIZE contentMode:PHImageContentModeAspectFit options:options
resultHandler:^(UIImage *image, NSDictionary * info) {
if (image) {
imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN];
[chatTableView.imagesInChatroom setObject:image forKey:[asset localIdentifier]];
[self loadImageAsset:asset image:image];
[SwiftUtil setCachedImageWithKey:asset image:image];
}
else {
LOGE(@"Can't read image");
}
}];
}
}
- (void) loadFileAsset:(NSString *)name {
@ -316,8 +327,13 @@
if ([key isEqualToString:@"localimage"]) {
// we did not load the image yet, so start doing so
if (_messageImageView.image == nil) {
NSData *data = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [[UIImage alloc] initWithData:data];
UIImage *cachedImage = [SwiftUtil getCachedImageWithKey:filePath] ? : [UIImage imageWithContentsOfFile:filePath];
UIImage *image = [SwiftUtil getCachedImageWithKey:filePath];
if (!image) {
image = [UIImage imageWithContentsOfFile:filePath];
if (image)
[SwiftUtil setCachedImageWithKey:filePath image:image];
}
if (image) {
[self loadImageAsset:nil image:image];
_imageGestureRecognizer.enabled = YES;
@ -343,8 +359,7 @@
[self loadImageAsset:nil image:image];
_imageGestureRecognizer.enabled = NO;
} else if ([fileName hasSuffix:@"JPG"] || [fileName hasSuffix:@"PNG"] || [fileName hasSuffix:@"jpg"] || [fileName hasSuffix:@"png"]) {
NSData *data = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [[UIImage alloc] initWithData:data];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
[self loadImageAsset:nil image:image];
_imageGestureRecognizer.enabled = YES;
} else {
@ -545,8 +560,7 @@
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:self.message];
if (filePath) {
NSData *data = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [[UIImage alloc] initWithData:data];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
[view setImage:image];
return;
}
@ -563,8 +577,7 @@
}
if (imageName) {
NSData *data = [NSData dataWithContentsOfFile:[LinphoneManager validFilePath:imageName]];
UIImage *image = [[UIImage alloc] initWithData:data];
UIImage *image = [UIImage imageWithContentsOfFile: [LinphoneManager validFilePath:imageName]];
if (image)
[view setImage:image];
else

View file

@ -373,9 +373,23 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width {
CGSize cached = [SwiftUtil getCachedMessageHeightWithCmessage:chat];
if (cached.height != 0) {
LOGI(@"ViewHeightForMessage - found cached value %f",cached.height);
return cached;
}
LOGI(@"ViewHeightForMessage - computing value");
CGSize size = [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
size.height += linphone_chat_message_is_forward(chat) || linphone_chat_message_is_reply(chat) ? REPLY_OR_FORWARD_TAG_HEIGHT : 0;
size.height += linphone_chat_message_is_reply(chat) ? REPLY_CHAT_BUBBLE_HEIGHT+5 : 0;
// No modifications of size below as it goes into cache
if ([SwiftUtil messageHeightCanBeCachedWithCmessage:chat]) {
[SwiftUtil setCachedMessageHeightWithCmessage:chat size:size];
}
return size;
}

View file

@ -18,6 +18,9 @@
*/
import UIKit
import Photos
import linphonesw
@objc class SwiftUtil: NSObject {
@ -69,5 +72,43 @@ import UIKit
return img
}
// Image cache
static var imageCache:[String:UIImage] = [:]
@objc static func getCachedImage(key:String) -> UIImage? {
return key != nil ? imageCache[key] : nil
}
@objc static func setCachedImage(key:String,image:UIImage) {
imageCache[key] = image
}
@objc static func resetCachedAsset() {
imageCache.removeAll()
}
// Chat bubble height cache :
static var cacheMessageSize:[String:CGSize] = [:]
@objc static func getCachedMessageHeight(cmessage:OpaquePointer) -> CGSize {
let message = ChatMessage.getSwiftObject(cObject: cmessage)
if let cached = cacheMessageSize[message.messageId] {
return cached
} else {
return .zero
}
}
@objc static func setCachedMessageHeight(cmessage:OpaquePointer, size:CGSize) {
let message = ChatMessage.getSwiftObject(cObject: cmessage)
cacheMessageSize[message.messageId] = size
}
@objc static func messageHeightCanBeCached(cmessage:OpaquePointer) -> Bool {
let message = ChatMessage.getSwiftObject(cObject: cmessage)
return (message.isOutgoing && [.Delivered, .DeliveredToUser, .Displayed].contains(message.state)) || (!message.isOutgoing && ![.InProgress, .FileTransferInProgress, .FileTransferError].contains(message.state))
}
}