Autoscale builtin pattern thumbnail

This commit is contained in:
Ali 2021-06-17 13:29:29 +04:00
parent dad3eca855
commit 01c5299c00
7 changed files with 37 additions and 19 deletions

View File

@ -121,22 +121,28 @@ public final class CachedPatternWallpaperMaskRepresentation: CachedMediaResource
public let keepDuration: CachedMediaRepresentationKeepDuration = .general
public let size: CGSize?
public let scaleFromCenter: CGFloat?
public var uniqueId: String {
if let size = self.size {
return "pattern-wallpaper-mask-\(Int(size.width))x\(Int(size.height))"
var result = "pattern-wallpaper-mask-\(Int(size.width))x\(Int(size.height))"
if let scaleFromCenter = self.scaleFromCenter {
result.append("-scale\(scaleFromCenter)")
}
return result
} else {
return "pattern-wallpaper-mask"
}
}
public init(size: CGSize?) {
public init(size: CGSize?, scaleFromCenter: CGFloat?) {
self.size = size
self.scaleFromCenter = scaleFromCenter
}
public func isEqual(to: CachedMediaResourceRepresentation) -> Bool {
if let to = to as? CachedPatternWallpaperMaskRepresentation {
return self.size == to.size
return self.size == to.size && self.scaleFromCenter == to.scaleFromCenter
} else {
return false
}

View File

@ -411,6 +411,10 @@ final class ThemeGridControllerNode: ASDisplayNode {
}
}
}
/*if !entries.isEmpty {
entries = [entries[0]]
}*/
let previous = previousEntries.swap(entries)
return (preparedThemeGridEntryTransition(context: context, from: previous ?? [], to: entries, interaction: interaction), previous == nil)

View File

@ -851,7 +851,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let dimensions = file.file.dimensions ?? PixelDimensions(width: 1440, height: 2960)
let size = dimensions.cgSize.fitted(CGSize(width: 1280.0, height: 1280.0))
let _ = self.context.account.postbox.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: true).start()
let _ = self.context.account.postbox.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: nil), complete: false, fetch: true).start()
}
}

View File

@ -4,6 +4,6 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor);
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor, CGFloat scaleFromCenter);
#endif /* Lottie_h */

View File

@ -83,7 +83,7 @@ CGSize aspectFillSize(CGSize size, CGSize bounds) {
@end
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor) {
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor, CGFloat scaleFromCenter) {
NSDate *startTime = [NSDate date];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
@ -104,9 +104,9 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
[xmlString replaceOccurrencesOfString:[NSString stringWithFormat:@"class=\"%@\"", styleName] withString:[NSString stringWithFormat:@"style=\"%@\"", styleValue] options:0 range:NSMakeRange(0, xmlString.length)];
}
char *zeroTerminatedData = xmlString.UTF8String;
const char *zeroTerminatedData = xmlString.UTF8String;
NSVGimage *image = nsvgParse(zeroTerminatedData, "px", 96);
NSVGimage *image = nsvgParse((char *)zeroTerminatedData, "px", 96);
if (image == nil || image->width < 1.0f || image->height < 1.0f) {
return nil;
}
@ -128,6 +128,10 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
CGContextScaleCTM(context, scale, scale);
CGContextTranslateCTM(context, (size.width - drawingSize.width) / 2.0, (size.height - drawingSize.height) / 2.0);
CGContextTranslateCTM(context, size.width / 2.0f, size.height / 2.0f);
CGContextScaleCTM(context, scaleFromCenter, scaleFromCenter);
CGContextTranslateCTM(context, -size.width / 2.0f, -size.height / 2.0f);
for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
if (!(shape->flags & NSVG_FLAGS_VISIBLE)) {
@ -135,7 +139,6 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
}
if (shape->fill.type != NSVG_PAINT_NONE) {
//CGContextSetFillColorWithColor(context, UIColorRGBA(shape->fill.color, shape->opacity).CGColor);
CGContextSetFillColorWithColor(context, [foregroundColor colorWithAlphaComponent:shape->opacity].CGColor);
bool isFirst = true;
@ -173,7 +176,6 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
}
if (shape->stroke.type != NSVG_PAINT_NONE) {
//CGContextSetStrokeColorWithColor(context, UIColorRGBA(shape->fill.color, shape->opacity).CGColor);
CGContextSetStrokeColorWithColor(context, [foregroundColor colorWithAlphaComponent:shape->opacity].CGColor);
CGContextSetMiterLimit(context, shape->miterLimit);
@ -196,10 +198,10 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
CGContextSetLineJoin(context, kCGLineJoinBevel);
break;
case NSVG_JOIN_MITER:
CGContextSetLineCap(context, kCGLineJoinMiter);
CGContextSetLineJoin(context, kCGLineJoinMiter);
break;
case NSVG_JOIN_ROUND:
CGContextSetLineCap(context, kCGLineJoinRound);
CGContextSetLineJoin(context, kCGLineJoinRound);
break;
default:
break;

View File

@ -424,7 +424,7 @@ private func fetchCachedPatternWallpaperMaskRepresentation(resource: MediaResour
if data.count > 5, let string = String(data: data.subdata(in: 0 ..< 5), encoding: .utf8), string == "<?xml" {
let size = representation.size ?? CGSize(width: 1440.0, height: 2960.0)
if let image = drawSvgImage(data, size, .black, .white) {
if let image = drawSvgImage(data, size, .black, .white, representation.scaleFromCenter ?? 1.0) {
if let alphaDestination = CGImageDestinationCreateWithURL(url as CFURL, kUTTypeJPEG, 1, nil) {
CGImageDestinationSetProperties(alphaDestination, [:] as CFDictionary)
@ -490,7 +490,7 @@ private func fetchCachedPatternWallpaperRepresentation(resource: MediaResource,
if data.count > 5, let string = String(data: data.subdata(in: 0 ..< 5), encoding: .utf8), string == "<?xml" {
let defaultSize = CGSize(width: 1440.0, height: 2960.0)
size = defaultSize
if let image = drawSvgImage(data, defaultSize, .black, .white) {
if let image = drawSvgImage(data, defaultSize, .black, .white, 1.0) {
maskImage = image
}
} else if let image = UIImage(data: data) {

View File

@ -362,13 +362,18 @@ private func patternWallpaperDatas(account: Account, accountManager: AccountMana
if let smallestRepresentation = smallestImageRepresentation(representations.map({ $0.representation })), let largestRepresentation = largestImageRepresentation(representations.map({ $0.representation })), let smallestIndex = representations.firstIndex(where: { $0.representation == smallestRepresentation }), let largestIndex = representations.firstIndex(where: { $0.representation == largestRepresentation }) {
let size: CGSize?
var scaleFromCenter: CGFloat?
switch mode {
case .thumbnail:
size = largestRepresentation.dimensions.cgSize.fitted(CGSize(width: 640.0, height: 640.0))
let factor = smallestRepresentation.dimensions.cgSize.width / largestRepresentation.dimensions.cgSize.width
if smallestRepresentation.dimensions.height >= 700 && abs(factor - 1.0) <= .ulpOfOne {
scaleFromCenter = 2.1
}
default:
size = nil
}
let maybeFullSize = combineLatest(accountManager.mediaBox.cachedResourceRepresentation(largestRepresentation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: false), account.postbox.mediaBox.cachedResourceRepresentation(largestRepresentation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: false))
let maybeFullSize = combineLatest(accountManager.mediaBox.cachedResourceRepresentation(largestRepresentation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: false), account.postbox.mediaBox.cachedResourceRepresentation(largestRepresentation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: false))
let signal = maybeFullSize
|> take(1)
@ -388,12 +393,12 @@ private func patternWallpaperDatas(account: Account, accountManager: AccountMana
let thumbnailData = Signal<Data?, NoError> { subscriber in
let fetchedDisposable = fetchedThumbnail.start()
let thumbnailDisposable = account.postbox.mediaBox.cachedResourceRepresentation(representations[smallestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: true).start(next: { next in
let thumbnailDisposable = account.postbox.mediaBox.cachedResourceRepresentation(representations[smallestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: true).start(next: { next in
subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []))
if next.complete, let data = try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedRead) {
accountManager.mediaBox.storeResourceData(representations[smallestIndex].representation.resource.id, data: data)
let _ = accountManager.mediaBox.cachedResourceRepresentation(representations[smallestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: true).start()
let _ = accountManager.mediaBox.cachedResourceRepresentation(representations[smallestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: true).start()
}
}, error: subscriber.putError, completed: subscriber.putCompletion)
@ -405,12 +410,12 @@ private func patternWallpaperDatas(account: Account, accountManager: AccountMana
let fullSizeData = Signal<(Data?, Bool), NoError> { subscriber in
let fetchedFullSizeDisposable = fetchedFullSize.start()
let fullSizeDisposable = account.postbox.mediaBox.cachedResourceRepresentation(representations[largestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: true).start(next: { next in
let fullSizeDisposable = account.postbox.mediaBox.cachedResourceRepresentation(representations[largestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: true).start(next: { next in
subscriber.putNext((next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []), next.complete))
if next.complete, let data = try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedRead) {
accountManager.mediaBox.storeResourceData(representations[largestIndex].representation.resource.id, data: data)
let _ = accountManager.mediaBox.cachedResourceRepresentation(representations[largestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size), complete: false, fetch: true).start()
let _ = accountManager.mediaBox.cachedResourceRepresentation(representations[largestIndex].representation.resource, representation: CachedPatternWallpaperMaskRepresentation(size: size, scaleFromCenter: scaleFromCenter), complete: false, fetch: true).start()
}
}, error: subscriber.putError, completed: subscriber.putCompletion)
@ -535,6 +540,7 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
let overlayImage = generateImage(arguments.drawingRect.size, rotatedContext: { size, c in
c.clear(CGRect(origin: CGPoint(), size: size))
let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage
if let image = image {
var fittedSize = CGSize(width: image.width, height: image.height)
if abs(fittedSize.width - arguments.boundingSize.width).isLessThanOrEqualTo(CGFloat(1.0)) {