mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Console: Image Attachments - Support optional "rotation" field in attached image. info.
This commit is contained in:
parent
57cbe53327
commit
da0d4f9529
8 changed files with 88 additions and 31 deletions
|
@ -30,10 +30,11 @@
|
|||
+ (NSArray*)listFiles:(NSString *)folderPath timeSorted:(BOOL)isTimeSorted largeFilesFirst:(BOOL)largeFilesFirst;
|
||||
|
||||
// return the file extension from a contentType
|
||||
+ (NSString*) fileExtensionFromContentType:(NSString*)contentType;
|
||||
+ (NSString*)fileExtensionFromContentType:(NSString*)contentType;
|
||||
|
||||
#pragma mark - Image
|
||||
+ (UIImage *)resize:(UIImage *)image toFitInSize:(CGSize)size;
|
||||
+ (UIImage*)forceImageOrientationUp:(UIImage*)imageSrc;
|
||||
+ (UIImage *)resize:(UIImage *)image toFitInSize:(CGSize)size;
|
||||
+ (UIImageOrientation)imageOrientationForRotationAngleInDegree:(NSInteger)angle;
|
||||
|
||||
@end
|
||||
|
|
|
@ -171,6 +171,30 @@
|
|||
|
||||
#pragma mark - Image
|
||||
|
||||
+ (UIImage*)forceImageOrientationUp:(UIImage*)imageSrc {
|
||||
if ((imageSrc.imageOrientation == UIImageOrientationUp) || (!imageSrc)) {
|
||||
// Nothing to do
|
||||
return imageSrc;
|
||||
}
|
||||
|
||||
UIGraphicsBeginImageContext(imageSrc.size);
|
||||
[imageSrc drawAtPoint:CGPointMake(0, 0)];
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
if (imageSrc.imageOrientation == UIImageOrientationRight) {
|
||||
CGContextRotateCTM (context, M_PI * 90 / 180.0f);
|
||||
} else if (imageSrc.imageOrientation == UIImageOrientationLeft) {
|
||||
CGContextRotateCTM (context, M_PI * -90 / 180.0f);
|
||||
} else if (imageSrc.imageOrientation == UIImageOrientationDown) {
|
||||
CGContextRotateCTM (context, M_PI * 180 / 180.0f);
|
||||
}
|
||||
|
||||
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return retImage;
|
||||
}
|
||||
|
||||
+ (UIImage *)resize:(UIImage *)image toFitInSize:(CGSize)size {
|
||||
UIImage *resizedImage = image;
|
||||
|
||||
|
@ -213,25 +237,19 @@
|
|||
return resizedImage;
|
||||
}
|
||||
|
||||
+ (UIImage*)forceImageOrientationUp:(UIImage*)imageSrc {
|
||||
if ((imageSrc.imageOrientation == UIImageOrientationUp) || (!imageSrc)) {
|
||||
// Nothing to do
|
||||
return imageSrc;
|
||||
+ (UIImageOrientation)imageOrientationForRotationAngleInDegree:(NSInteger)angle {
|
||||
NSInteger modAngle = angle % 360;
|
||||
|
||||
UIImageOrientation orientation = UIImageOrientationUp;
|
||||
if (45 <= modAngle && modAngle < 135) {
|
||||
return UIImageOrientationRight;
|
||||
} else if (135 <= modAngle && modAngle < 225) {
|
||||
return UIImageOrientationDown;
|
||||
} else if (225 <= modAngle && modAngle < 315) {
|
||||
return UIImageOrientationLeft;
|
||||
}
|
||||
|
||||
UIGraphicsBeginImageContext(imageSrc.size);
|
||||
[imageSrc drawAtPoint:CGPointMake(0, 0)];
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
if (imageSrc.imageOrientation == UIImageOrientationRight) {
|
||||
CGContextRotateCTM (context, M_PI * 90 / 180.0f);
|
||||
} else if (imageSrc.imageOrientation == UIImageOrientationLeft) {
|
||||
CGContextRotateCTM (context, M_PI * -90 / 180.0f);
|
||||
} else if (imageSrc.imageOrientation == UIImageOrientationDown) {
|
||||
CGContextRotateCTM (context, M_PI * 180 / 180.0f);
|
||||
}
|
||||
|
||||
return UIGraphicsGetImageFromCurrentImageContext();;
|
||||
return orientation;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef enum : NSUInteger {
|
|||
@property (nonatomic) NSDictionary *attachmentInfo;
|
||||
@property (nonatomic) NSString *thumbnailURL;
|
||||
@property (nonatomic) NSDictionary *thumbnailInfo;
|
||||
@property (nonatomic) UIImageOrientation thumbnailOrientation;
|
||||
@property (nonatomic) NSString *previewURL;
|
||||
@property (nonatomic) NSString *uploadId;
|
||||
@property (nonatomic) CGFloat uploadProgress;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#import "MatrixSDKHandler.h"
|
||||
#import "AppSettings.h"
|
||||
#import "MXCTools.h"
|
||||
|
||||
NSString *const kRoomMessageLocalPreviewKey = @"kRoomMessageLocalPreviewKey";
|
||||
NSString *const kRoomMessageUploadIdKey = @"kRoomMessageUploadIdKey";
|
||||
|
@ -55,18 +56,34 @@ static NSAttributedString *messageSeparator = nil;
|
|||
_messageType = RoomMessageTypeText;
|
||||
if ([mxHandler isSupportedAttachment:event]) {
|
||||
// Note: event.eventType is equal here to MXEventTypeRoomMessage
|
||||
|
||||
// Set default thumbnail orientation
|
||||
_thumbnailOrientation = UIImageOrientationUp;
|
||||
|
||||
NSString *msgtype = event.content[@"msgtype"];
|
||||
if ([msgtype isEqualToString:kMXMessageTypeImage]) {
|
||||
_messageType = RoomMessageTypeImage;
|
||||
// Retrieve content url/info
|
||||
_attachmentURL = event.content[@"url"];
|
||||
_attachmentInfo = event.content[@"info"];
|
||||
// Handle thumbnail url/info
|
||||
// Handle legacy thumbnail url/info (Not defined anymore in recent attachments)
|
||||
_thumbnailURL = event.content[@"thumbnail_url"];
|
||||
_thumbnailInfo = event.content[@"thumbnail_info"];
|
||||
if (!_thumbnailURL) {
|
||||
// Suppose _attachmentURL is a matrix content uri, we use SDK to get the well adapted thumbnail from server
|
||||
_thumbnailURL = [mxHandler thumbnailURLForContent:_attachmentURL inViewSize:self.contentSize withMethod:MXThumbnailingMethodScale];
|
||||
|
||||
// Check whether the image has been uploaded with an orientation
|
||||
if (_attachmentInfo[@"rotation"]) {
|
||||
// Currently the matrix content server provides thumbnails by ignoring the original image orientation.
|
||||
// We store here the actual orientation to apply it on downloaded thumbnail.
|
||||
_thumbnailOrientation = [MXCTools imageOrientationForRotationAngleInDegree:[_attachmentInfo[@"rotation"] integerValue]];
|
||||
|
||||
// Rotate the current content size (if need)
|
||||
if (_thumbnailOrientation == UIImageOrientationLeft || _thumbnailOrientation == UIImageOrientationRight) {
|
||||
_contentSize = CGSizeMake(_contentSize.height, _contentSize.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ([msgtype isEqualToString:kMXMessageTypeAudio]) {
|
||||
// Not supported yet
|
||||
|
@ -445,7 +462,13 @@ static NSAttributedString *messageSeparator = nil;
|
|||
}
|
||||
}
|
||||
}
|
||||
_contentSize = CGSizeMake(width, height);
|
||||
|
||||
// Check here thumbnail orientation
|
||||
if (_thumbnailOrientation == UIImageOrientationLeft || _thumbnailOrientation == UIImageOrientationRight) {
|
||||
_contentSize = CGSizeMake(height, width);
|
||||
} else {
|
||||
_contentSize = CGSizeMake(width, height);
|
||||
}
|
||||
} else {
|
||||
_contentSize = CGSizeMake(40, 40);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
typedef void (^blockMXCImageView_onClick)(MXCImageView *imageView, NSString* title);
|
||||
|
||||
- (void)setImageURL:(NSString *)imageURL withPreviewImage:(UIImage*)previewImage;
|
||||
- (void)setImageURL:(NSString *)imageURL withImageOrientation:(UIImageOrientation)orientation andPreviewImage:(UIImage*)previewImage;
|
||||
|
||||
// Use this boolean to hide activity indicator during image downloading
|
||||
@property (nonatomic) BOOL hideActivityIndicator;
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
@interface MXCImageView () {
|
||||
NSString *imageURL;
|
||||
UIImage *currentImage;
|
||||
UIImageOrientation imageOrientation;
|
||||
|
||||
UIImage *currentImage;
|
||||
|
||||
// the loading view is composed with the spinner and a pie chart
|
||||
// the spinner is display until progress > 0
|
||||
|
@ -409,17 +411,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setImageURL:(NSString *)anImageURL withPreviewImage:(UIImage*)previewImage {
|
||||
- (void)setImageURL:(NSString *)anImageURL withImageOrientation:(UIImageOrientation)orientation andPreviewImage:(UIImage*)previewImage {
|
||||
// Remove any pending observers
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
imageURL = anImageURL;
|
||||
|
||||
imageURL = anImageURL;
|
||||
if (!imageURL) {
|
||||
// Set preview by default
|
||||
self.image = previewImage;
|
||||
return;
|
||||
}
|
||||
|
||||
// Store image orientation
|
||||
imageOrientation = orientation;
|
||||
|
||||
// Check whether the image download is in progress
|
||||
MediaLoader* loader = [MediaManager existingDownloaderForURL:imageURL inFolder:mediaFolder];
|
||||
if (loader) {
|
||||
|
@ -436,7 +441,12 @@
|
|||
// Retrieve the image from cache
|
||||
UIImage* image = [MediaManager loadCachePictureForURL:imageURL inFolder:mediaFolder];
|
||||
if (image) {
|
||||
self.image = image;
|
||||
if (imageOrientation != UIImageOrientationUp) {
|
||||
self.image = [UIImage imageWithCGImage:image.CGImage scale:1.0 orientation:imageOrientation];
|
||||
} else {
|
||||
self.image = image;
|
||||
}
|
||||
|
||||
[self stopActivityIndicator];
|
||||
} else {
|
||||
// Set preview until the image is loaded
|
||||
|
@ -464,7 +474,11 @@
|
|||
// update the image
|
||||
UIImage* image = [MediaManager loadCachePictureForURL:imageURL inFolder:mediaFolder];
|
||||
if (image) {
|
||||
self.image = image;
|
||||
if (imageOrientation != UIImageOrientationUp) {
|
||||
self.image = [UIImage imageWithCGImage:image.CGImage scale:1.0 orientation:imageOrientation];
|
||||
} else {
|
||||
self.image = image;
|
||||
}
|
||||
}
|
||||
// remove the observers
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
thumbnailURL = [mxHandler thumbnailURLForContent:roomMember.avatarUrl inViewSize:self.pictureView.frame.size withMethod:MXThumbnailingMethodCrop];
|
||||
}
|
||||
self.pictureView.mediaFolder = kMediaManagerThumbnailFolder;
|
||||
[self.pictureView setImageURL:thumbnailURL withPreviewImage:[UIImage imageNamed:@"default-profile"]];
|
||||
[self.pictureView setImageURL:thumbnailURL withImageOrientation:UIImageOrientationUp andPreviewImage:[UIImage imageNamed:@"default-profile"]];
|
||||
|
||||
// Round image view
|
||||
[self.pictureView.layer setCornerRadius:self.pictureView.frame.size.width / 2];
|
||||
|
|
|
@ -1497,7 +1497,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
|
|||
highResImageView.stretchable = YES;
|
||||
highResImageView.fullScreen = YES;
|
||||
highResImageView.mediaFolder = self.roomId;
|
||||
[highResImageView setImageURL:url withPreviewImage:attachment.image];
|
||||
[highResImageView setImageURL:url withImageOrientation:UIImageOrientationUp andPreviewImage:attachment.image];
|
||||
|
||||
// Add tap recognizer to hide attachment
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideAttachmentView)];
|
||||
|
@ -2036,7 +2036,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
|
|||
// Suppose this url is a matrix content uri, we use SDK to get the well adapted thumbnail from server
|
||||
avatarThumbURL = [mxHandler thumbnailURLForContent:message.senderAvatarUrl inViewSize:cell.pictureView.frame.size withMethod:MXThumbnailingMethodCrop];
|
||||
}
|
||||
[cell.pictureView setImageURL:avatarThumbURL withPreviewImage:[UIImage imageNamed:@"default-profile"]];
|
||||
[cell.pictureView setImageURL:avatarThumbURL withImageOrientation:UIImageOrientationUp andPreviewImage:[UIImage imageNamed:@"default-profile"]];
|
||||
[cell.pictureView.layer setCornerRadius:cell.pictureView.frame.size.width / 2];
|
||||
cell.pictureView.clipsToBounds = YES;
|
||||
cell.pictureView.backgroundColor = [UIColor redColor];
|
||||
|
@ -2127,7 +2127,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
|
|||
if (message.previewURL) {
|
||||
preview = [MediaManager loadCachePictureForURL:message.previewURL inFolder:self.roomId];
|
||||
}
|
||||
[cell.attachmentView setImageURL:url withPreviewImage:preview];
|
||||
[cell.attachmentView setImageURL:url withImageOrientation:message.thumbnailOrientation andPreviewImage:preview];
|
||||
|
||||
if (url && message.attachmentURL && message.attachmentInfo) {
|
||||
// Add tap recognizer to open attachment
|
||||
|
|
Loading…
Reference in a new issue