Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
368 views
in Technique[技术] by (71.8m points)

xamarin.ios - App crashes on applying image effects (brightness) using slider in iOS

I am using a Image view and applying brightness effects to the image of the image view based on the slider value. Slider value ranges from -100 to +100. On continuously moving the slider, app gets closed. I have even tried with disposing the context but same issue exits. Please refer the below code and help me to solve.

    UIImageView imageView;
    private float brightnessAmount;
    private bool isBrightnessApplied;
    private ImageEffect effects;
    private CIContext filterContext;
    UIImage originalImage;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        
        effects = ImageEffect.Brightness;
        originalImage = UIImage.FromBundle("image.jpg");

        var frame = this.View.Frame;

        UIView mainView = new UIView();
        mainView.Frame = frame;

        imageView = new UIImageView();
        imageView.Frame = new CGRect(frame.Left, frame.Top, frame.Width, frame.Height - 100);
        imageView.Image = UIImage.FromBundle("image.jpg");
        mainView.Add(imageView);

        UISlider slider = new UISlider();
        slider.Frame = new CGRect(frame.Left, imageView.Frame.Bottom, frame.Width, 100);
        slider.MinValue = -100;
        slider.MaxValue = 100;
        slider.ValueChanged += Slider_ValueChanged;
        mainView.Add(slider);
        this.Add(mainView);
    }

   private void Slider_ValueChanged(object sender, EventArgs e)
    {
        var amount = (sender as UISlider).Value;

        amount = amount > 100 ? 100 : amount < -100 ? -100 : amount;
       
        amount = amount / 100;
        CIImage currentImage = GetFilteredCIImage(effects);
        CIColorControls colorCtrls = new CIColorControls() { Image = currentImage };
        if (effects == ImageEffect.Brightness)
        {
            colorCtrls.Brightness = amount;
            brightnessAmount = amount;
            isBrightnessApplied = true;
        }
       
        if (filterContext == null )
            filterContext = CIContext.FromOptions(null);
        var outputImage = colorCtrls.OutputImage;
        var result = filterContext.CreateCGImage(outputImage, outputImage.Extent);
        filterContext.ClearCaches();
     
        imageView.Image = UIImage.FromImage(result);
        result.Dispose();
        result = null;
        outputImage.Dispose();
        outputImage = null;
    }

    private CIImage GetFilteredCIImage(ImageEffect effect)
    {
        CIImage currentImage = CIImage.FromCGImage(originalImage.CGImage);
        if (effect == ImageEffect.None) return currentImage;
       
        if ( isBrightnessApplied)
        {
            CIColorControls colorCtrls = new CIColorControls() { Image = currentImage };
            colorCtrls.Brightness = brightnessAmount;
            currentImage = colorCtrls.OutputImage;
            colorCtrls.Dispose();
        }
        return currentImage;
    }
question from:https://stackoverflow.com/questions/65879413/app-crashes-on-applying-image-effects-brightness-using-slider-in-ios

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you want to change the brightness of Image , check the following code .

Note :you need to test it on a real device because it use GPU context . On a simulator it will have a delay .

using CoreGraphics;
using CoreImage;
using Foundation;
using System;
using UIKit;
using OpenGLES;
using System.Threading.Tasks;

namespace App10
{
    public partial class ViewController : UIViewController
    {


        UIImageView imageView;
        CIContext context;
        UIImage originalImage;

        CIColorControls colorCtrls;
        bool isbusy;
        public ViewController (IntPtr handle) : base (handle)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            originalImage = UIImage.FromBundle("Images.png");

            var frame = this.View.Frame;

            UIView mainView = new UIView();
            mainView.Frame = frame;

            imageView = new UIImageView();
            imageView.Frame = new CGRect(frame.Left, frame.Top, frame.Width, frame.Height - 100);
            imageView.Image = UIImage.FromBundle("Images.png");
            mainView.Add(imageView);

            UISlider slider = new UISlider();
            slider.Frame = new CGRect(frame.Left, imageView.Frame.Bottom, frame.Width, 100);
            slider.MinValue = -100;
            slider.MaxValue = 100;
            slider.ValueChanged += Slider_TouchUpInside; 
            mainView.Add(slider);
            this.Add(mainView);


            colorCtrls = new CIColorControls();
            colorCtrls.InputImage = new CIImage(originalImage);

            // Create the context only once, and re-use it
            var contextOptions = new CIContextOptions();
            contextOptions.UseSoftwareRenderer = false; // gpu vs. cpu
                                                        // On save of the image, create a new context with highqual attributes and re-apply the filter... 
            contextOptions.HighQualityDownsample = false;
            contextOptions.PriorityRequestLow = false; // high queue order it
            contextOptions.CIImageFormat = (int)CIFormat.ARGB8; // use 32bpp, vs. 64|128bpp 
            context = CIContext.FromOptions(contextOptions);


            // Perform any additional setup after loading the view, typically from a nib.
        }

        private async void Slider_TouchUpInside(object sender, EventArgs e)
        {
            if(!isbusy)
            {
                isbusy = true;
                var slider = sender as UISlider;
                imageView.Image = await FilterImageAsync(slider.Value / 100);
                isbusy = false;
            }
        }


      
        async Task<UIImage> FilterImageAsync(float value)
        {  

             var transformImage = new Func<UIImage>(() => {
                    colorCtrls.Brightness = value;
                    CIImage input = new CIImage(originalImage);
                    var output = colorCtrls.OutputImage;
                    var cgImage = context.CreateCGImage(output, input.Extent);
                    var filteredImage = new UIImage(cgImage);
                    return filteredImage;
                });
          
            
            UIImage image = await Task.Run<UIImage>(transformImage);
            return image;
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...