Reproduce Springboard's icon shine with WebKit

2019-04-17 13:29发布

anyone got any ideas on how to reproduce the gloss of iPhone app icons using WebKit and CSS3 and/or a transparent overlay image? Is this even possible?

2条回答
家丑人穷心不美
2楼-- · 2019-04-17 13:54

iPhone OS uses the following images to compose the icon:

  1. AppIconMask.png
  2. AppIconShadow.png
  3. AppIconOverlay.png (optional)
查看更多
劫难
3楼-- · 2019-04-17 13:57

This is how I have implemented the above using only the AppIconOverlay.png in my app. I kind of like the desired effect.

It doesn't have the shadow, but I'm sure if you really wanted it you could modify the code in order to suit your needs. In terms of the AppIconMask.png I couldn't really see any need in using this since I use the #import <QuartzCore/QuartzCore.h> framework in order to achieve the desired effect by adding a layer.masksToBounds and layer.cornerRadius.

I hope this works for anyone who is interested in achieving the Apple Springboard overlay effect. Oh and thank-you to rpetrich for providing those images.

I apologise for the lack of comments in the code. It's a culmination of code from similar existing implementations scattered all over the internet. So I'd like to thank all of those people for providing those bits and pieces of code that are used as well.

- (UIImage *)getIconOfSize:(CGSize)size icon:(UIImage *)iconImage withOverlay:(UIImage *)overlayImage {
 UIImage *icon = [self scaleImage:iconImage toResolution:size.width];

 CGRect iconBoundingBox = CGRectMake (0, 0, size.width, size.height);
 CGRect overlayBoundingBox = CGRectMake (0, 0, size.width, size.height);

 CGContextRef myBitmapContext = [self createBitmapContextOfSize:size];

 CGContextSetRGBFillColor (myBitmapContext, 1, 1, 1, 1);
 CGContextFillRect (myBitmapContext, iconBoundingBox);
 CGContextDrawImage(myBitmapContext, iconBoundingBox, icon.CGImage);
 CGContextDrawImage(myBitmapContext, overlayBoundingBox, overlayImage.CGImage);
 UIImage *result = [UIImage imageWithCGImage: CGBitmapContextCreateImage (myBitmapContext)];
 CGContextRelease (myBitmapContext);

 return result;
}

- (CGContextRef)createBitmapContextOfSize:(CGSize)size {
 CGContextRef    context = NULL;
 CGColorSpaceRef colorSpace;
 void *          bitmapData;
 int             bitmapByteCount;
 int             bitmapBytesPerRow;

 bitmapBytesPerRow   = (size.width * 4);
 bitmapByteCount     = (bitmapBytesPerRow * size.height);

 colorSpace = CGColorSpaceCreateDeviceRGB();
 bitmapData = malloc( bitmapByteCount );

 if (bitmapData == NULL) {
  fprintf (stderr, "Memory not allocated!");
  return NULL;
 }

 context = CGBitmapContextCreate (bitmapData,
          size.width,
          size.height,
          8,      // bits per component
          bitmapBytesPerRow,
          colorSpace,
          kCGImageAlphaPremultipliedLast);

 CGContextSetAllowsAntialiasing (context,NO);

 if (context== NULL) {
  free (bitmapData);
  fprintf (stderr, "Context not created!");
  return NULL;
 }

 CGColorSpaceRelease( colorSpace );

 return context;
}

- (UIImage *)scaleImage:(UIImage *)image toResolution:(int)resolution {
 CGFloat width = image.size.width; 
 CGFloat height = image.size.height;
 CGRect bounds = CGRectMake(0, 0, width, height);

    // If already at the minimum resolution, return the original image, otherwise scale.
    if (width <= resolution && height <= resolution) {
        return image;
    } else {
        CGFloat ratio = width/height;

        if (ratio > 1) {
            bounds.size.width = resolution;
            bounds.size.height = bounds.size.width / ratio;
        } else {
            bounds.size.height = resolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    UIGraphicsBeginImageContext(bounds.size);
    [image drawInRect:CGRectMake(0.0, 0.0, bounds.size.width, bounds.size.height)];
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

Usage:

UIImage *overlayImage = [UIImage imageNamed:@"AppIconOverlay.png"];
UIImage *profileImage = [Helper getIconOfSize:CGSizeMake(59, 60) icon:image withOverlay:overlayImage];
[profilePictureImageView setImage:profileImage];

profilePictureImageView.layer.masksToBounds = YES;
profilePictureImageView.layer.cornerRadius = 10.0;
profilePictureImageView.layer.borderColor = [[UIColor grayColor] CGColor];
profilePictureImageView.layer.borderWidth = 1.0;
查看更多
登录 后发表回答