Wiem, że możesz to zrobić za pomocą UIImageView, ale czy można to zrobić z UIImage? Chcę, aby właściwość tablicy animacji obrazów UIImageView była tablicą tego samego obrazu, ale z różnymi nieprzezroczystościami. Myśli?
Odpowiedzi:
Po prostu musiałem to zrobić, ale pomyślałem, że rozwiązanie Stevena będzie powolne. Miejmy nadzieję, że powinno to wykorzystywać sprzęt graficzny. Utwórz kategorię na UIImage:
- (UIImage *)imageByApplyingAlpha:(CGFloat) alpha {
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
CGContextSetAlpha(ctx, alpha);
CGContextDrawImage(ctx, area, self.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Ustaw krycie widoku, w którym jest on wyświetlany.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"SomeName.png"]];
imageView.alpha = 0.5; //Alpha runs from 0.0 to 1.0
Użyj tego w animacji. Możesz zmienić wartość alfa w animacji na pewien czas.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
//Set alpha
[UIView commitAnimations];
UIButton
dokładnie to, czego potrzebowałem.
Na podstawie odpowiedzi Alexey Ishkov, ale w Swift
Użyłem rozszerzenia klasy UIImage.
Swift 2:
Rozszerzenie UIImage:
extension UIImage {
func imageWithAlpha(alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
drawAtPoint(CGPointZero, blendMode: .Normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Używać:
let image = UIImage(named: "my_image")
let transparentImage = image.imageWithAlpha(0.5)
Swift 3/4/5:
Zauważ, że ta implementacja zwraca opcjonalny UIImage. Dzieje się tak, ponieważ w Swift 3 UIGraphicsGetImageFromCurrentImageContext
zwraca teraz opcjonalny. Ta wartość może wynosić zero, jeśli kontekst jest zerowy lub nie został utworzony za pomocą UIGraphicsBeginImageContext
.
Rozszerzenie UIImage:
extension UIImage {
func image(alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: .zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Używać:
let image = UIImage(named: "my_image")
let transparentImage = image?.image(alpha: 0.5)
Swift 3
wersję.
jest dużo prostsze rozwiązanie:
- (UIImage *)tranlucentWithAlpha:(CGFloat)alpha
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:alpha];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Zdaję sobie sprawę, że to dość późno, ale potrzebowałem czegoś takiego, więc wymyśliłem szybką i brudną metodę, aby to zrobić.
+ (UIImage *) image:(UIImage *)image withAlpha:(CGFloat)alpha{
// Create a pixel buffer in an easy to use format
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(m_PixelBuf, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
//alter the alpha
int length = height * width * 4;
for (int i=0; i<length; i+=4)
{
m_PixelBuf[i+3] = 255*alpha;
}
//create a new image
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef newImgRef = CGBitmapContextCreateImage(ctx);
CGColorSpaceRelease(colorSpace);
CGContextRelease(ctx);
free(m_PixelBuf);
UIImage *finalImage = [UIImage imageWithCGImage:newImgRef];
CGImageRelease(newImgRef);
return finalImage;
}
setImage:withAlpha:
image:withAlpha:
?
Hej, hej, dzięki od użytkownika Xamarin! :) Tutaj jest przetłumaczone na c #
//***************************************************************************
public static class ImageExtensions
//***************************************************************************
{
//-------------------------------------------------------------
public static UIImage WithAlpha(this UIImage image, float alpha)
//-------------------------------------------------------------
{
UIGraphics.BeginImageContextWithOptions(image.Size,false,image.CurrentScale);
image.Draw(CGPoint.Empty, CGBlendMode.Normal, alpha);
var newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage;
}
}
Przykład użycia:
var MySupaImage = UIImage.FromBundle("opaquestuff.png").WithAlpha(0.15f);
taki sam wynik jak inne, inny styl:
extension UIImage {
func withAlpha(_ alpha: CGFloat) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { _ in
draw(at: .zero, blendMode: .normal, alpha: alpha)
}
}
}
Swift 5:
extension UIImage {
func withAlphaComponent(_ alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
draw(at: .zero, blendMode: .normal, alpha: alpha)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
Jeśli eksperymentujesz z renderowaniem metalu i wyodrębniasz CGImage wygenerowany przez imageByApplyingAlpha w pierwszej odpowiedzi, możesz skończyć z renderowaniem metalu, które jest większe niż się spodziewasz. Podczas eksperymentowania z Metal możesz chcieć zmienić jedną linię kodu w imageByApplyingAlpha:
UIGraphicsBeginImageContextWithOptions (self.size, NO, 1.0f);
// UIGraphicsBeginImageContextWithOptions (self.size, NO, 0.0f);
Jeśli używasz urządzenia o współczynniku skali 3,0, takim jak iPhone 11 Pro Max, współczynnik skali 0,0 pokazany powyżej da ci obraz CG, który jest trzy razy większy niż się spodziewasz. Zmiana współczynnika skalowania na 1,0 powinna uniknąć skalowania.
Miejmy nadzieję, że ta odpowiedź zaoszczędzi początkującym wielu irytacji.