UIImageの不透明度/アルファを設定するにはどうすればよいですか?


81

UIImageViewでこれを実行できることは知っていますが、UIImageで実行できますか?UIImageViewのアニメーション画像の配列プロパティを同じ画像の配列にしたいのですが、不透明度が異なります。考え?

回答:


122

私はこれを行う必要がありましたが、スティーブンの解決策は遅いだろうと思いました。これはうまくいけばグラフィックスハードウェアを使用する必要があります。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;
}

3
なぜ私がこれを必要としたのかさえ思い出せません:)
マーティ

素晴らしい解決策!ニックありがとう!
クリストファー

1
バックグラウンドレンダリングは予測できないため、メインスレッドでUIGraphicsBeginImageContextWithOptionsを呼び出していることを確認してください。
Steven Veltema 2012年

1
Appleによると、iOS 4以降では、どのスレッドでもUIGraphicsBeginImageContextWithOptionsを呼び出すことができます。
アリ2013年

6
トンのおかげで、うまくいきます。iOS開発に関するロジスティクスの初心者向けに、UIImageのカテゴリを作成する手順を以下に示します。1.プロジェクトのディレクターを右クリックして、[新しいファイル]を選択します。2.表示される画面で、Objective-Cカテゴリのファイルタイプを選択します。3.回答のコードを.mファイルに追加し、メソッドの宣言を.hファイルに追加します。4.画像を透明にするために使用するファイルで、ファイルを#importします。5.UIImageのインスタンスでメソッドimageByApplyingAlphaを使用します。
ダニー

79

に表示されるビューの不透明度を設定します。

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"SomeName.png"]];
imageView.alpha = 0.5; //Alpha runs from 0.0 to 1.0

これをアニメーションで使用します。アニメーションのアルファを一定期間変更できます。

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
//Set alpha
[UIView commitAnimations];

ええ、私は不透明度を絶えず変更するためにタイマーでこのようにする必要があるかもしれないと思っていましたが、アニメーション画像の配列プロパティの配列を持っている方がはるかに簡単で、それ自体でアニメーション化できると思っていました。
マーティ

アニメーションデリゲートを使用して、ハートビートのように「イン」および「アウト」でアニメーション化できます。タイマーを使用しないでください。アニメーションによってアルファがスムーズに変更されます。幸運を。
Mats Stijlaart 2011

3
これは、開発者がUIImageViewを使用している場合にのみ機能します。質問は明らかにそうではないことを示しています。
Raul Huerta 2014

1
これは、CALayerで表示されるUIImageで機能し、画像をまったく変更せずにlayer.opacityを設定するだけです。ありがとうマット!
クリス

すごい!上の作品UIButton、私は必要なまさに、。
NecipAllef 2016

52

Alexey Ishkovの回答に基づいていますが、Swiftで

UIImageクラスの拡張機能を使用しました。

スウィフト2:

UIImage拡張機能:

extension UIImage {
    func imageWithAlpha(alpha: CGFloat) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        drawAtPoint(CGPointZero, blendMode: .Normal, alpha: alpha)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}

使用するには:

let image = UIImage(named: "my_image")
let transparentImage = image.imageWithAlpha(0.5)

スウィフト3/4/5:

この実装はオプションのUIImageを返すことに注意してください。これは、Swift3でUIGraphicsGetImageFromCurrentImageContextオプションが返されるようになったためです。コンテキストがnilの場合、またはで作成されていない場合、この値はnilになる可能性がありますUIGraphicsBeginImageContext

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
    }
}

使用するには:

let image = UIImage(named: "my_image")
let transparentImage = image?.image(alpha: 0.5)

私はこのSwift 3バージョンが好きです。
AechoLiu 2017年

ありがとう。Swift 4でも同じように機能し、これを反映するように回答を更新しました。
zeeshan

ブラボー卿、ブラボー
ライアンブロディ

17

はるかに簡単な解決策があります:

- (UIImage *)tranlucentWithAlpha:(CGFloat)alpha
{
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:alpha];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

1
おそらく受け入れられた答えだったはずです。結果を得るための最速/最も効率的な方法
Will Von Ullrich 2017

4

これはかなり遅いと思いますが、私はこのようなものが必要だったので、これを行うために迅速で汚い方法を作り上げました。

+ (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;
}

2
より良い名前は次のようになりますsetImage:withAlpha:
アレクサンダー

8
セットは通常、プロパティを参照し、何らかの方法でレシーバーの状態を変更します。名前を付けたほうがいいimage:withAlpha:ですか?
ジョナサン。

2
ええ。また、setを呼び出すと、新しい画像を返すのではなく、渡された同じオブジェクトの設定が適用されます。
システム

4

Xamarinユーザーからのおかげでねえねえ!:)ここでそれは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;
        }

}

使用例:

var MySupaImage = UIImage.FromBundle("opaquestuff.png").WithAlpha(0.15f);

1

他の人と同じ結果、異なるスタイル:

extension UIImage {

    func withAlpha(_ alpha: CGFloat) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { _ in
            draw(at: .zero, blendMode: .normal, alpha: alpha)
        }
    }

}

1

スウィフト5:

extension UIImage {
  func withAlphaComponent(_ alpha: CGFloat) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    defer { UIGraphicsEndImageContext() }

    draw(at: .zero, blendMode: .normal, alpha: alpha)
    return UIGraphicsGetImageFromCurrentImageContext()
  }
}

0

Metalレンダリングを試していて、最初の応答でimageByApplyingAlphaによって生成されたCGImageを抽出している場合、予想よりも大きいMetalレンダリングになってしまう可能性があります。Metalの実験中に、imageByApplyingAlphaの1行のコードを変更したい場合があります。

    UIGraphicsBeginImageContextWithOptions (self.size, NO, 1.0f);
//  UIGraphicsBeginImageContextWithOptions (self.size, NO, 0.0f);

iPhone 11 Pro Maxのように倍率3.0のデバイスを使用している場合、上記の倍率0.0を使用すると、予想の3倍のCGImageが得られます。倍率を1.0に変更すると、スケーリングを回避できます。

うまくいけば、この返信は初心者の多くの悪化を救うでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.