Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8616909
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T05:43:51+00:00 2026-06-12T05:43:51+00:00

I am working on an application that allows the user to select an image

  • 0

I am working on an application that allows the user to select an image (camera or gallery), then draw on that image with their finger. The area that they draw becomes the transparent portion of a mask. A second image is then drawn below the first image.

I’ve been working on improving performance, especially on the iPad 3 and I seem to have hit a wall. I am new to iOS and Objective-C.

So my question is: What can I do to improve the drawing performance of my application?

I used this tutorial as a starting point for my code.

First I draw to a cache context:

- (void) drawToCache {
    CGRect dirtyPoint1;
    CGRect dirtyPoint2;
    UIColor *color;

    if (point1.x > -1){
        hasDrawn = YES;

        maskContext = CGLayerGetContext(maskLayer);
        blackBackgroundContext = CGLayerGetContext(blackBackgroundLayer);

        if (!doUndo){
            color = [UIColor whiteColor];
            CGContextSetBlendMode(maskContext, kCGBlendModeColor);
        }
        else{
            color = [UIColor clearColor];
            CGContextSetBlendMode(maskContext, kCGBlendModeClear);
        }

        CGContextSetShouldAntialias(maskContext, YES);

        CGContextSetRGBFillColor(blackBackgroundContext, 0.0, 0.0, 0.0, 1.0);
        CGContextFillRect(blackBackgroundContext, self.bounds);

        CGContextSetStrokeColorWithColor(maskContext, [color CGColor]);
        CGContextSetLineCap(maskContext, kCGLineCapRound);
        CGContextSetLineWidth(maskContext, brushSize);

        double x0 = (point0.x > -1) ? point0.x : point1.x; //after 4 touches we should have a back anchor point, if not, use the current anchor point
        double y0 = (point0.y > -1) ? point0.y : point1.y; //after 4 touches we should have a back anchor point, if not, use the current anchor point
        double x1 = point1.x;
        double y1 = point1.y;
        double x2 = point2.x;
        double y2 = point2.y;
        double x3 = point3.x;
        double y3 = point3.y;

        double xc1 = (x0 + x1) / 2.0;
        double yc1 = (y0 + y1) / 2.0;
        double xc2 = (x1 + x2) / 2.0;
        double yc2 = (y1 + y2) / 2.0;
        double xc3 = (x2 + x3) / 2.0;
        double yc3 = (y2 + y3) / 2.0;

        double len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
        double len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
        double len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));

        double k1 = len1 / (len1 + len2);
        double k2 = len2 / (len2 + len3);

        double xm1 = xc1 + (xc2 - xc1) * k1;
        double ym1 = yc1 + (yc2 - yc1) * k1;
        double xm2 = xc2 + (xc3 - xc2) * k2;
        double ym2 = yc2 + (yc3 - yc2) * k2;

        double smooth_value = 0.5;
        float ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
        float ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;
        float ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
        float ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

        CGContextMoveToPoint(maskContext, point1.x, point1.y);
        CGContextAddCurveToPoint(maskContext, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, point2.x, point2.y);
        CGContextStrokePath(maskContext);

        dirtyPoint1 = CGRectMake(point1.x-(brushSize/2), point1.y-(brushSize/2), brushSize, brushSize);
        dirtyPoint2 = CGRectMake(point2.x-(brushSize/2), point2.y-(brushSize/2), brushSize, brushSize);
        [self setNeedsDisplayInRect:CGRectUnion(dirtyPoint1, dirtyPoint2)];
    }
}

And my drawRect:

- (void)drawRect:(CGRect)rect {
    CGRect imageRect = CGRectMake(0, 0, 1024, 668);
    CGSize size =  CGSizeMake(1024, 668);

    //Draw the user touches to the context, this creates a black and white image to convert into a mask
    UIGraphicsBeginImageContext(size);
    CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES);
    CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), imageRect, blackBackgroundLayer);
    CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), imageRect, maskLayer);
    CGImageRef maskRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
    UIGraphicsEndImageContext();

    //Make the mask
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false);
    //Mask the user image
    CGImageRef masked = CGImageCreateWithMask([self.original CGImage], mask);

    UIGraphicsBeginImageContext(size);
    CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), imageRect, backgroundTextureLayer);
    CGImageRef background = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
    UIGraphicsEndImageContext();

    //Flip the context so everything is right side up
    CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, 668);
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);

    //Draw the background on the context
    CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, background);

    //Draws the mask on the context
    CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, masked);

    //Release everything to prevent memory leaks
    CGImageRelease(background);
    CGImageRelease(maskRef);
    CGImageRelease(mask);
    CGImageRelease(masked);
}

I spent yesterday researching these questions:

How can I improve CGContextFillRect and CGContextDrawImage performance

CGContextDrawImage very slow on iPhone 4

Drawing in CATiledLayer with CoreGraphics CGContextDrawImage

iPhone: How do I add layers to UIView's root layer to display an image with the content property?

iPhone CGContextDrawImage and UIImageJPEGRepresentation drastically slowing down application

Any help is appreciated!

Thanks,
Kevin

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T05:43:52+00:00Added an answer on June 12, 2026 at 5:43 am

    I can give you some tips but you’re going to need to experiment to see where the problems are (using Instruments):

    • do not assume you need to draw the whole view – when you need to dirty some area, use setNeedsDisplayInRect. Then in the drawRect only update the dirty area.

    • the above means your maskRef is much smaller and easier to construct

    • instead of ‘[self.original CGImage]’, create a smaller subregion image using CGImageCreateWithImageInRect(), which lets you select a subsection of an image, then use that smaller image in conjunction with the mask.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm currently working on an ASP.Net WebForms application that allows a user to select
I'm working on an application that allows the user to send a file using
I'm working on an application that allows users to add their own RSS feeds
I'm working on an asp.net application that allows the user to update data for
I'm working on an application that allows users to generate university schedules and then
I have a drawing application in Android that allows the user to draw with
I am working on an application that should allow user select a code from
I'm currently working on a web application that allows the user to upload files
I am working on an application that allows user to authenticate with Devise and
http://f.cl.ly/items/350X3c0h0A0k3s3f1R1h/Screen%20Shot%202012-03-27%20at%202.53.41%20PM.png I'm working on an application that'll allow a user to select a range

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.