ios - Draw a shape over a high res image? -


i want able draw line on high resolution photo (e.g. 8megapixel image) in specific place.

that simple enough thing, , there many posts problem cgcontext "drawing space" doesn't seem same high res image.

i can draw line , save image, problem drawing line in specific location. coordinate spaces seem different each other. think there must scale factor missing or understanding messed up.

so question is:

how draw on image, "aspect fit" screen (but higher resolution) , have drawing (in case line) in same position on screen , final full resolution composited image?

example image: enter image description here

the red line line drawing. should go center of start target (thetarget) center of end target (theend).

i have simplified drawing function down posting here, suspect whole thinking/approach wrong.

import uikit  class viewcontroller: uiviewcontroller {  @iboutlet weak var imageview: uiimageview!   @iboutlet weak var thetarget: uiimageview! @iboutlet weak var theend: uiimageview!  var linecolor = uicolor.redcolor() var targetpos : cgpoint! var endpos : cgpoint! var originalimage : uiimage!  override func viewdidload() {     super.viewdidload()      imageview.image = uiimage(named: "reference.jpg")     originalimage = imageview.image      drawtheline()  }   func drawtheline () {     uigraphicsbeginimagecontext(originalimage!.size);      // draw original image background     originalimage?.drawatpoint(cgpointmake(0, 0))      // pass 2: draw line on top of original image     let context = uigraphicsgetcurrentcontext();     cgcontextsetlinewidth(context, 10.0);      targetpos = thetarget.frame.origin     endpos = theend.frame.origin      cgcontextmovetopoint(context, targetpos.x, targetpos.y);     cgcontextaddlinetopoint(context, endpos.x, endpos.y)     cgcontextsetstrokecolorwithcolor(context, linecolor.cgcolor)     cgcontextstrokepath(context);      imageview.image = uigraphicsgetimagefromcurrentimagecontext() }  @ibaction func savebutton(sender: anyobject) {     // create new image     let newimage = uigraphicsgetimagefromcurrentimagecontext();     uigraphicsendimagecontext();      uiimagewritetosavedphotosalbum(newimage!, nil, nil, nil ) }   override func didreceivememorywarning() {     super.didreceivememorywarning()     // dispose of resources can recreated. }   @ibaction func handlepan(recognizer:uipangesturerecognizer) {     let translation = recognizer.translationinview(self.view)     if let view = recognizer.view {         view.center = cgpoint(x:view.center.x + translation.x,             y:view.center.y + translation.y)     }     recognizer.settranslation(cgpointzero, inview: self.view)      //redraw line     drawtheline()      print("the start pos of line is: ", thetarget.frame.origin, " , end pos is: ", theend.frame.origin)  }   } 

i had exact problem while ago, wrote uiimageview extension maps image view's coordinates image coordinates, when fill mode .scaleaspectfit.

extension uiimageview {      func pointinaspectscalefitimagecoordinates(point:cgpoint) -> cgpoint {          if let img = image {              let imagesize = img.size             let imageviewsize = frame.size              let imgratio = imagesize.width/imagesize.height // ratio of image before scaling.             let imgviewratio = imageviewsize.width/imageviewsize.height // ratio of image view              let ratio = (imgratio > imgviewratio) ? imagesize.width/imageviewsize.width:imagesize.height/imageviewsize.height // ratio of image before scaling after scaling.              let xoffset = (imagesize.width-(imageviewsize.width*ratio))*0.5 // x-offset of image on-screen (as gets centered)             let yoffset = (imagesize.height-(imageviewsize.height*ratio))*0.5 // y-offset of image on-screen (as gets centered)              let subimgorigin = cgpoint(x: point.x*ratio, y: point.y*ratio); // origin of image (relative origin of view)              return cgpoint(x: subimgorigin.x+xoffset, y: subimgorigin.y+yoffset);         }         return cgpointzero     } } 

you should able use in drawtheline function quite easily:

func drawtheline () {     uigraphicsbeginimagecontext(originalimage!.size);      // draw original image background     originalimage?.drawatpoint(cgpointmake(0, 0))      // pass 2: draw line on top of original image     let context = uigraphicsgetcurrentcontext();     cgcontextsetlinewidth(context, 10.0);      targetpos = imageview.pointinaspectscalefitimagecoordinates(thetarget.frame.origin)     endpos = imageview.pointinaspectscalefitimagecoordinates(theend.frame.origin)      cgcontextmovetopoint(context, targetpos.x, targetpos.y);     cgcontextaddlinetopoint(context, endpos.x, endpos.y)     cgcontextsetstrokecolorwithcolor(context, linecolor.cgcolor)     cgcontextstrokepath(context);      imageview.image = uigraphicsgetimagefromcurrentimagecontext() } 

Comments