skip to Main Content

I have a cropped image (mainImage) that I allow users to draw on top of using their fingers. The red zig-zag on screen A. shows the finger drawn portion. Right now, using the code below, the newly drawn image context (red zig-zag) is shoved into the same bounds as the cropped image and I end up with a distorted zig-zag (screenshot B.). You can see how the red zig-zag has been shoved into the bounds of the cropped (mainImage).

What I am trying to achieve is an image that combines the two contexts from mainImage and drawImage without distorting the proportions of either photo. So that only the portions of the red zig-zag that overlap the mainImage will be drawn in the new context as in screenshot C.(photoshopped image of the results I would like). Right now, the commitDrawingWithOpacity: method results with screenshot B. and I would like the results of screenshot C.

I’ve tried CGContextClipToRect, CGContextClipToMask, and also tried creating a new rect for the draw image, among other things but so far no success. I’ve been stuck on this issue for almost a month now (self taught) and it is one of the very last things I need to do before I can submit my app to apple. So any help would be GREATLY appreciated. Here’s a link to the code I am using https://github.com/dblapps/DAScratchPad

Here’s the size of each:

drawImage.size = (width=320, height=568) // iPhone 5 screen size

mainImage.size = (width=260, height=800) // size of cropped image

my imageView is set to aspect fit ratio.

- (void) commitDrawingWithOpacity:(CGFloat)opacity {
    UIGraphicsBeginImageContext(mainImage.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(ctx, 1.0f, -1.0f);
    CGContextTranslateCTM(ctx, 0.0f, -mainImage.size.height);

    CGRect rect = CGRectMake(0.0f, 0.0f, mainImage.size.width, mainImage.size.height);

    if (mainImage != nil) {
        CGContextDrawImage(ctx, rect, mainImage.CGImage);
    }

    CGContextSetAlpha(ctx, opacity);
    CGContextDrawImage(ctx, rect, drawImage.CGImage);
    mainImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.layer.contents = (id)mainImage.CGImage;
    drawLayer.contents = nil;
    drawImage = nil;
}

Using the function AVMakeRectWithAspectRatioInsideRect I have been able to get the correct size ratio for my mainImage but still have had no luck with getting anything to work right.

enter image description here

Below is a photoshopped screenshot of the results I am trying to achieve. Screenshot B (above) is what I am getting with my current code.

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    For me, I need to utilize both functions: AVMakeRectWithAspectRatioInsideRect & CGImageCreateWithImageInRect to get the desired results. My problem was the aspect ratio difference between my mainImage and the drawImage. So AVMakeRectWithAspectRatioInsideRect gave me a new rectangle with the correct size ratio and origin points for my mainImage. After that, I used CGImageCreateWithImageInRect to lay the [drawImage CGImage] into the new rectangle and Presto! My drawImage and mainImage create a new context with the exact same aspect ratio. No more distortion or skewing of images. Working code is posted below.

    - (void) commitDrawingWithOpacity:(CGFloat)opacity {
    
        CGRect drawRect = AVMakeRectWithAspectRatioInsideRect(mainImage.size, self.frame);
    
        UIGraphicsBeginImageContext(mainImage.size);
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextScaleCTM(ctx, 1.0f, -1.0f);
        CGContextTranslateCTM(ctx, 0.0f, -mainImage.size.height);
    
        CGRect rect = CGRectMake(0.0f, 0.0f, mainImage.size.width, mainImage.size.height);
    
        if (mainImage != nil) {
            CGContextDrawImage(ctx, rect, mainImage.CGImage);
        }
    
        CGImageRef imageRef = CGImageCreateWithImageInRect([drawImage CGImage], drawRect);
    
        CGContextSetAlpha(ctx, opacity);
        CGContextDrawImage(ctx, rect, imageRef);
    
        mainImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        self.layer.contents = (id)mainImage.CGImage;
        drawLayer.contents = nil;
        drawImage = nil;
    }
    

  2. You are drawing the drawImage using the proportions of the mainImage hence why it’s is being distorted. You should keep the proportions of the drawImage and just position it correctly. Here’s a potential starting point for you to tweak – it’s hard to tell exactly what you are trying to achieve from your question:

    CGRect drawImageRect = (CGRect){
      .origin = {
        .x = -((drawImage.size.width - mainImage.size.width)   / 2),
        .y = -((drawImage.size.height - mainImage.size.height) / 2),
      },
      .size = drawImage.size,
    };
    

    This rect uses the original size and then adjusts the origin of where the image is drawn

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search