Skip to content

Commit

Permalink
perf(ios): draw backgroundImage asynchronously for performance (#3844)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwcg authored May 14, 2024
1 parent 6e0903d commit 78cf381
Showing 1 changed file with 54 additions and 44 deletions.
98 changes: 54 additions & 44 deletions ios/sdk/component/view/HippyView.m
Original file line number Diff line number Diff line change
Expand Up @@ -640,64 +640,74 @@ - (BOOL)getLayerContentForColor:(UIColor *)color completionBlock:(void (^)(UIIma
if (!self.backgroundImageUrl && !self.gradientObject) {
contentBlock(image);
return YES;
}
else if (self.backgroundImageUrl) {
} else if (self.backgroundImageUrl) {
CGSize size = theFrame.size;
if (0 >= size.width || 0 >= size.height) {
contentBlock(nil);
return YES;
}
CGFloat backgroundPositionX = self.backgroundPositionX;
CGFloat backgroundPositionY = self.backgroundPositionY;
HippyBackgroundImageCacheManager *weakBackgroundCacheManager = [self backgroundCachemanager];
[weakBackgroundCacheManager imageWithUrl:self.backgroundImageUrl completionHandler:^(UIImage *decodedImage, NSError *error) {
if (error) {
HippyLogError(@"weakBackgroundCacheManagerLog %@", error);

__weak __typeof(self)weakSelf = self;
__weak HippyBackgroundImageCacheManager *weakBackgroundCacheManager = [self backgroundCachemanager];
NSString *backgroundImageUrl = self.backgroundImageUrl;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (!decodedImage) {
contentBlock(nil);
}

UIGraphicsBeginImageContextWithOptions(theFrame.size, NO, image.scale);
//draw background image
CGSize imageSize = decodedImage.size;
CGSize targetSize = UIEdgeInsetsInsetRect(theFrame, [self bordersAsInsets]).size;

CGSize drawSize = makeSizeConstrainWithType(imageSize, targetSize, backgroundSize);

CGPoint originOffset = CGPointMake((targetSize.width - drawSize.width) / 2.f, (targetSize.height - drawSize.height) / 2.f);

[decodedImage drawInRect:CGRectMake(borderInsets.left + backgroundPositionX + originOffset.x,
borderInsets.top + backgroundPositionY + originOffset.y,
drawSize.width,
drawSize.height)];
//draw border
CGSize size = theFrame.size;
[image drawInRect:(CGRect) { CGPointZero, size }];

//output image
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
contentBlock(resultingImage);
}];
[weakBackgroundCacheManager imageWithUrl:backgroundImageUrl completionHandler:^(UIImage *decodedImage, NSError *error) {
if (error) {
HippyLogError(@"weakBackgroundCacheManagerLog %@", error);
return;
}
if (!decodedImage) {
contentBlock(nil);
}

UIGraphicsBeginImageContextWithOptions(theFrame.size, NO, image.scale);
//draw background image
CGSize imageSize = decodedImage.size;
CGSize targetSize = UIEdgeInsetsInsetRect(theFrame, borderInsets).size;
CGSize drawSize = makeSizeConstrainWithType(imageSize, targetSize, backgroundSize);
CGPoint originOffset = CGPointMake((targetSize.width - drawSize.width) / 2.0,
(targetSize.height - drawSize.height) / 2.0);

[decodedImage drawInRect:CGRectMake(borderInsets.left + backgroundPositionX + originOffset.x,
borderInsets.top + backgroundPositionY + originOffset.y,
drawSize.width,
drawSize.height)];
//draw border
CGSize size = theFrame.size;
[image drawInRect:(CGRect) { CGPointZero, size }];

//output image
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
contentBlock(resultingImage);
}];
});
return NO;
}
else if (self.gradientObject) {
} else if (self.gradientObject) {
CGSize size = theFrame.size;
if (0 >= size.width || 0 >= size.height) {
contentBlock(nil);
return NO;
return YES;
}
CanvasInfo info = {size, {0,0,0,0}, {{0,0},{0,0},{0,0},{0,0}}};
info.size = size;
info.cornerRadii = cornerRadii;
UIGraphicsBeginImageContextWithOptions(size, NO, image.scale);
[self.gradientObject drawInContext:UIGraphicsGetCurrentContext() canvasInfo:info];
[image drawInRect:(CGRect) { CGPointZero, size }];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
contentBlock(resultingImage);
HippyGradientObject *gradientObject = self.gradientObject;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
CanvasInfo info = {size, {0,0,0,0}, {{0,0},{0,0},{0,0},{0,0}}};
info.size = size;
info.cornerRadii = cornerRadii;
UIGraphicsBeginImageContextWithOptions(size, NO, image.scale);
[gradientObject drawInContext:UIGraphicsGetCurrentContext() canvasInfo:info];
[image drawInRect:(CGRect) { CGPointZero, size }];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
contentBlock(resultingImage);
});
return NO;
}
return YES;
}
Expand Down

0 comments on commit 78cf381

Please sign in to comment.