0

I have a public static method that returns a color replaced image (I pass in a black image, and it returns the same image with red instead of black, or whatever color I choose).

It looks like this:

public class ColorImage
{
    public static UIImage GetColoredImage(UIImage image, UIColor color)
    {
        UIImage coloredImage = null;
        if (color == null)
        {
            color = UIColor.FromRGB(44, 132, 248);
        }

        UIGraphics.BeginImageContextWithOptions(image.Size, false, UIScreen.MainScreen.Scale);
        using (CGContext context = UIGraphics.GetCurrentContext())
        {
            context.TranslateCTM(0, image.Size.Height);
            context.ScaleCTM(1.0f, -1.0f);

            var rect = new RectangleF(0, 0, (float)image.Size.Width, (float)image.Size.Height);

            context.ClipToMask(rect, image.CGImage);
            context.SetFillColor(color.CGColor);
            context.FillRect(rect);

            coloredImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
        }
        return coloredImage;
    }
}

I was talking with a colleague and we thought it might be better to store images (color and not color), and colors we plan on using throughout our application in public static fields. That way, if I needed to use one of these colors or images I could just call:

Textfield.BackgroundColor = ColorCache.MainColor;
Textfield.Image = ImageCache.UserImage;

Or something along those lines. This is for an iOS app using Xamarin. Is there a problem with doing it this way? Thought it might even make some of our listviews load faster because they're not grabbing images and processing the color on them over and over.

aufty
  • 407
  • 2
  • 9
  • 26

2 Answers2

1

Instead of loading everything at once like in a static, what would be a better approach is to use caching. So that an image once loaded will be saved in the memory and wont be created next time its asked for. But an image that is not yet asked will not occupy any memory.

You can make use of normal properties or static properties.

Or create a private readonly dictionary with color name and the image as key and value. If the key is available when requested return it else create and add to dictionary and return the image.

Some sample code :

public static class ColorImage
{
    private static readonly Dictionary<UIColor, UIImage> _colorDictionary = new Dictionary<UIColor, UIImage>();

    public static UIImage GetColoredImage(UIImage image, UIColor color)
    {
        if(_colorDictionary.ContainsKey(color))
        {
           _colorDictionary.TryGetValue(color, out image);
        }
        else 
        {
            //create the image
            _colorDictionary.Add(color, image);
        }
        return image;
    }
}
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
0

I think it is doesn't make any sense to load unnecessary data to the memory. what you are intend to do is to create an image for each color you might think of, and if the user will select that particular color it will be ready to use.

if you were building a server module it was a bit different perspective, but as long as one user selects color, and the only thing you should do is painting it, what is the point of intialize an array with images?

it will just blast your memory for the chance that the user might select this color..

TTomer
  • 356
  • 2
  • 11
  • The images are used all over the application, as in the same image multiple times, even on the same screen. Right now it's coloring the image over and over again, in the case of a listview. I don't know if ios optimizes this by using the same image, or if it grabs the image every time from the disk... I'd rather sacrifice the small amount of memory for the image for the performance gains – aufty Aug 04 '16 at 15:47
  • 1
    if that's the case, a better approach in my opinion would be: create a singleton, every time only one image processing will be available, once an image is ready keep it in a Dictionary, next time the singlton will be fired it will look for that image, if it's exist take it - else, generate a new one. that way you will always have only the data you use "on-demand" and not just creating various images like a roulette. – TTomer Aug 04 '16 at 15:52