1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-02 09:27:55 +01:00
Telegram/Telegraph/TGAttachmentVideoCell.m
2016-02-25 01:03:51 +01:00

298 lines
12 KiB
Objective-C

#import "TGAttachmentVideoCell.h"
#import "TGModernGalleryTransitionView.h"
#import "TGFont.h"
#import "TGPhotoEditorUtils.h"
#import "TGMediaAsset+TGMediaEditableItem.h"
#import "TGVideoEditAdjustments.h"
#import "TGVTAcceleratedVideoView.h"
NSString *const TGAttachmentVideoCellIdentifier = @"AttachmentVideoCell";
@interface TGAttachmentVideoCell () <TGModernGalleryTransitionView>
{
SMetaDisposable *_adjustmentsDisposable;
TGVTAcceleratedVideoView *_videoView;
}
@end
@implementation TGAttachmentVideoCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
_iconView = [[UIImageView alloc] init];
_iconView.contentMode = UIViewContentModeCenter;
[self addSubview:_iconView];
_durationLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_durationLabel.backgroundColor = [UIColor clearColor];
_durationLabel.font = TGSystemFontOfSize(12);
_durationLabel.textColor = [UIColor whiteColor];
[self addSubview:_durationLabel];
_gradientView.hidden = false;
[self bringSubviewToFront:_cornersView];
_adjustmentsDisposable = [[SMetaDisposable alloc] init];
}
return self;
}
- (void)dealloc
{
[_adjustmentsDisposable dispose];
}
- (void)setAsset:(TGMediaAsset *)asset signal:(SSignal *)signal
{
[super setAsset:asset signal:signal];
_durationLabel.text = [NSString stringWithFormat:@"%d:%02d", (int)ceil(asset.videoDuration) / 60, (int)ceil(asset.videoDuration) % 60];
[_durationLabel sizeToFit];
CGRect durationFrame = _durationLabel.frame;
durationFrame.size = CGSizeMake(ceil(_durationLabel.frame.size.width), ceil(_durationLabel.frame.size.height));
_durationLabel.frame = durationFrame;
if (asset.subtypes & TGMediaAssetSubtypeVideoTimelapse)
_iconView.image = [UIImage imageNamed:@"ModernMediaItemTimelapseIcon"];
else if (asset.subtypes & TGMediaAssetSubtypeVideoHighFrameRate)
_iconView.image = [UIImage imageNamed:@"ModernMediaItemSloMoIcon"];
else
_iconView.image = [UIImage imageNamed:@"ModernMediaItemVideoIcon"];
SSignal *adjustmentsSignal = [self.editingContext adjustmentsSignalForItem:self.asset];
__weak TGAttachmentVideoCell *weakSelf = self;
[_adjustmentsDisposable setDisposable:[adjustmentsSignal startWithNext:^(TGVideoEditAdjustments *next)
{
__strong TGAttachmentVideoCell *strongSelf = weakSelf;
if (strongSelf == nil)
return;
if ([next isKindOfClass:[TGVideoEditAdjustments class]])
[strongSelf _layoutImageForOriginalSize:next.originalSize cropRect:next.cropRect cropOrientation:next.cropOrientation];
else
[strongSelf _layoutImageWithoutAdjustments];
}]];
}
- (void)_transformLayoutForOrientation:(UIImageOrientation)orientation originalSize:(CGSize *)inOriginalSize cropRect:(CGRect *)inCropRect
{
if (inOriginalSize == NULL || inCropRect == NULL)
return;
CGSize originalSize = *inOriginalSize;
CGRect cropRect = *inCropRect;
if (orientation == UIImageOrientationLeft)
{
cropRect = CGRectMake(cropRect.origin.y, originalSize.width - cropRect.size.width - cropRect.origin.x, cropRect.size.height, cropRect.size.width);
originalSize = CGSizeMake(originalSize.height, originalSize.width);
}
else if (orientation == UIImageOrientationRight)
{
cropRect = CGRectMake(originalSize.height - cropRect.size.height - cropRect.origin.y, cropRect.origin.x, cropRect.size.height, cropRect.size.width);
originalSize = CGSizeMake(originalSize.height, originalSize.width);
}
else if (orientation == UIImageOrientationDown)
{
cropRect = CGRectMake(originalSize.width - cropRect.size.width - cropRect.origin.x, originalSize.height - cropRect.size.height - cropRect.origin.y, cropRect.size.width, cropRect.size.height);
}
*inOriginalSize = originalSize;
*inCropRect = cropRect;
}
- (void)_layoutImageForOriginalSize:(CGSize)originalSize cropRect:(CGRect)cropRect cropOrientation:(UIImageOrientation)cropOrientation
{
self.imageView.transform = CGAffineTransformMakeRotation(TGRotationForOrientation(cropOrientation));
[self _transformLayoutForOrientation:cropOrientation originalSize:&originalSize cropRect:&cropRect];
CGFloat ratio = (cropRect.size.width > cropRect.size.height) ? self.frame.size.height / cropRect.size.height : self.frame.size.width / cropRect.size.width;
CGSize fillSize = CGSizeMake(cropRect.size.width * ratio, cropRect.size.height * ratio);
self.imageView.frame = CGRectMake(-cropRect.origin.x * ratio + (self.frame.size.width - fillSize.width) / 2, -cropRect.origin.y * ratio + (self.frame.size.height - fillSize.height) / 2, originalSize.width * ratio, originalSize.height * ratio);
}
- (void)_layoutImageWithoutAdjustments
{
self.imageView.transform = CGAffineTransformIdentity;
self.imageView.frame = self.bounds;
}
- (void)layoutSubviews
{
[super layoutSubviews];
_iconView.frame = CGRectMake(0, self.frame.size.height - 19, 19, 19);
CGSize durationSize = _durationLabel.frame.size;
_durationLabel.frame = CGRectMake(self.frame.size.width - durationSize.width - 4, self.frame.size.height - durationSize.height - 2, durationSize.width, durationSize.height);
}
- (UIImage *)transitionImageSquared
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0f);
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) cornerRadius:TGAttachmentMenuCellCornerRadius] addClip];
UIImage *image = self.imageView.image;
CGSize originalSize = CGSizeZero;
CGRect cropRect = CGRectZero;
UIImageOrientation cropOrientation = UIImageOrientationUp;
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[self.editingContext adjustmentsForItem:self.asset];
if ([adjustments isKindOfClass:[TGVideoEditAdjustments class]])
{
originalSize = adjustments.originalSize;
cropRect = adjustments.cropRect;
cropOrientation = adjustments.cropOrientation;
__block UIImage *editedImage = nil;
[[self.editingContext thumbnailImageSignalForItem:self.asset withUpdates:false synchronous:true] startWithNext:^(UIImage *next)
{
editedImage = next;
}];
if (editedImage != nil)
image = editedImage;
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGSize fillSize = TGScaleToFillSize(image.size, self.bounds.size);
if (CGRectEqualToRect(cropRect, CGRectZero))
{
[image drawInRect:CGRectMake((self.bounds.size.width - fillSize.width) / 2, (self.bounds.size.height - fillSize.height) / 2, fillSize.width, fillSize.height)];
}
else
{
CGContextConcatCTM(context, TGVideoCropTransformForOrientation(cropOrientation, self.frame.size, false));
CGFloat ratio = (cropRect.size.width > cropRect.size.height) ? self.frame.size.height / cropRect.size.height : self.frame.size.width / cropRect.size.width;
CGSize fillSize = CGSizeMake(cropRect.size.width * ratio, cropRect.size.height * ratio);
[image drawInRect:CGRectMake(-cropRect.origin.x * ratio + (self.frame.size.width - fillSize.width) / 2, -cropRect.origin.y * ratio + (self.frame.size.height - fillSize.height) / 2, originalSize.width * ratio, originalSize.height * ratio)];
}
CGContextRestoreGState(context);
UIImage *transitionImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return transitionImage;
}
- (UIImage *)transitionImage
{
if (fabs(self.frame.size.width - self.frame.size.height) < FLT_EPSILON)
{
return [self transitionImageSquared];
}
UIImage *sourceImage = self.imageView.image;
CGSize originalSize = CGSizeZero;
CGRect cropRect = CGRectZero;
UIImageOrientation cropOrientation = UIImageOrientationUp;
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[self.editingContext adjustmentsForItem:self.asset];
if ([adjustments isKindOfClass:[TGVideoEditAdjustments class]])
{
originalSize = adjustments.originalSize;
cropRect = adjustments.cropRect;
cropOrientation = adjustments.cropOrientation;
__block UIImage *editedImage = nil;
[[self.editingContext thumbnailImageSignalForItem:self.asset withUpdates:false synchronous:true] startWithNext:^(UIImage *next)
{
editedImage = next;
}];
if (editedImage != nil)
sourceImage = editedImage;
}
if (CGRectEqualToRect(cropRect, CGRectZero))
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0f);
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) cornerRadius:TGAttachmentMenuCellCornerRadius] addClip];
CGSize fillSize = TGScaleToFillSize(sourceImage.size, self.bounds.size);
[sourceImage drawInRect:CGRectMake((self.bounds.size.width - fillSize.width) / 2, (self.bounds.size.height - fillSize.height) / 2, fillSize.width, fillSize.height)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
else
{
//CGFloat maxSide = MAX(sourceImage.size.width, sourceImage.size.height);
//CGSize maxSize = CGSizeMake(maxSide, maxSide);
UIImage *croppedImage = TGPhotoEditorCrop(sourceImage, cropOrientation, 0, cropRect, CGSizeZero, originalSize, false);
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0f);
CGFloat scale = 1.0f;
CGSize scaledBoundsSize = CGSizeZero;
CGSize scaledImageSize = CGSizeZero;
if (croppedImage.size.width > croppedImage.size.height)
{
scale = self.frame.size.height / croppedImage.size.height;
scaledBoundsSize = CGSizeMake(self.frame.size.width / scale, croppedImage.size.height);
scaledImageSize = CGSizeMake(croppedImage.size.width * scale, croppedImage.size.height * scale);
if (scaledImageSize.width < self.frame.size.width)
{
scale = self.frame.size.width / croppedImage.size.width;
scaledBoundsSize = CGSizeMake(croppedImage.size.width, self.frame.size.height / scale);
}
}
else
{
scale = self.frame.size.width / croppedImage.size.width;
scaledBoundsSize = CGSizeMake(croppedImage.size.width, self.frame.size.height / scale);
scaledImageSize = CGSizeMake(croppedImage.size.width * scale, croppedImage.size.height * scale);
if (scaledImageSize.width < self.frame.size.width)
{
scale = self.frame.size.height / croppedImage.size.height;
scaledBoundsSize = CGSizeMake(self.frame.size.width / scale, croppedImage.size.height);
}
}
CGRect rect = self.bounds;
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) cornerRadius:TGAttachmentMenuCellCornerRadius] addClip];
CGContextScaleCTM(context, scale, scale);
[croppedImage drawInRect:CGRectMake((scaledBoundsSize.width - croppedImage.size.width) / 2,
(scaledBoundsSize.height - croppedImage.size.height) / 2,
croppedImage.size.width,
croppedImage.size.height)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
}
@end