剪裁框和圖片剪裁

圖片處理中經(jīng)常用的圖片剪裁陋气,就是通過剪裁框確定圖片剪裁的區(qū)域,然后剪去該區(qū)域的圖片迫筑,今天實(shí)現(xiàn)了一下趟大,其實(shí)圖片剪裁本身不難,主要剪裁框封裝發(fā)了點(diǎn)時(shí)間铣焊,主要功能可以拖動(dòng)四個(gè)角縮放逊朽,但不能超出父視圖,拖動(dòng)四個(gè)邊單方向縮放曲伊,不能超出父視圖叽讳,拖動(dòng)中間部分單單移動(dòng),不改變大小坟募,不能超出父視圖岛蚤。下面列舉一些主要代碼。
四個(gè)角的處理代碼:

-(void)btnPanGesture:(UIPanGestureRecognizer*)panGesture
{
    UIView *vw = panGesture.view;
    CGRect oldFrame = self.frame;
    CGRect oldIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
    
    CGPoint transport = [panGesture translationInView:vw];
    if (vw.tag == 4) {
        self.width = self.preFrame.size.width + transport.x;
        self.height = self.preFrame.size.height + transport.y;
    }
    else if(vw.tag == 3)
    {
        self.x = self.preFrame.origin.x + transport.x;
        self.width = self.preFrame.size.width - transport.x;
        self.height = self.preFrame.size.height + transport.y;
    }
    else if(vw.tag == 2)
    {
        self.width = self.preFrame.size.width + transport.x;
        self.y = self.preFrame.origin.y + transport.y;
        self.height = self.preFrame.size.height - transport.y;
    }
    else if(vw.tag == 1)
    {
        self.x = self.preFrame.origin.x + transport.x;
        self.width = self.preFrame.size.width - transport.x;
        self.y = self.preFrame.origin.y + transport.y;
        self.height = self.preFrame.size.height - transport.y;
    }
    if (panGesture.state == UIGestureRecognizerStateEnded) {
        self.preFrame = self.frame;
    }
    if (self.width < MinWidth || self.height < MinHeight) {
        self.frame = oldFrame;
    }
    CGRect newFrame = self.frame;
    if (newFrame.size.width * newFrame.size.height > oldFrame.size.height * oldFrame.size.width) {
        
        CGRect newIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
        if (newFrame.size.width * newFrame.size.height > newIntersectRect.size.width * newIntersectRect.size.height) {
            self.frame = oldFrame;
        }
    }
    self.preCenter = self.center;
}

我是通過視圖于父視圖的frame的交集部分的面積判斷是否超出父視圖的懈糯。
四個(gè)邊的控制代碼:

-(void)viewPanGesture:(UIPanGestureRecognizer*)panGesture
{
    UIView *vw = panGesture.view;
    CGRect oldFrame = self.frame;
    CGRect oldIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
    
    CGPoint transport = [panGesture translationInView:vw];
    if (vw.tag == 1) {
        self.y = self.preFrame.origin.y + transport.y;
        self.height = self.preFrame.size.height - transport.y;
    }
    else if(vw.tag == 2)
    {
        self.x = self.preFrame.origin.x + transport.x;
        self.width = self.preFrame.size.width - transport.x;
    }
    else if(vw.tag == 3)
    {
        self.height = self.preFrame.size.height + transport.y;
    }
    else if(vw.tag == 4)
    {
        self.width = self.preFrame.size.width + transport.x;
    }
    if (panGesture.state == UIGestureRecognizerStateEnded) {
        self.preFrame = self.frame;
    }
    if (self.width < MinWidth || self.height < MinHeight) {
        self.frame = oldFrame;

    }
    self.preCenter = self.center;
    CGRect newFrame = self.frame;
    if (newFrame.size.width * newFrame.size.height > oldFrame.size.height * oldFrame.size.width) {
        
        CGRect newIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
        if (oldIntersectRect.size.width * oldIntersectRect.size.height >= newIntersectRect.size.width * newIntersectRect.size.height) {
            self.frame = oldFrame;
            self.preCenter = self.preCenter;
        }
        
    }

}

中間部分移動(dòng)的控制代碼:

-(void)contentViewPanGestureAction:(UIPanGestureRecognizer*)panGesture
{
    CGPoint transport = [panGesture translationInView:self];
    CGRect oldFrame = self.frame;
    CGRect oldIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
    CGFloat oldMj = oldIntersectRect.size.width * oldIntersectRect.size.height;
    
    self.center = CGPointMake(self.preCenter.x + transport.x, self.preCenter.y + transport.y);
    
    if (panGesture.state == UIGestureRecognizerStateEnded) {
        
        self.preCenter = self.center;
    }
    CGRect newIntersectRect  = CGRectIntersection(self.frame, self.superview.bounds);
    CGFloat newMj = newIntersectRect.size.width * newIntersectRect.size.height;
    
    if (newMj < oldMj) {
        self.frame = oldFrame;
        self.preCenter = self.center;
    }
}

剪裁框?qū)崿F(xiàn)的核心代碼如上涤妒,個(gè)人覺得最不好處理的是對(duì)超出父視圖的控制,要保證不能超出父視圖赚哗,個(gè)人主要用到的是通過子視圖與父視圖的交集部分的面積的改變來獲知是否超出父視圖她紫,如果超出父視圖,就會(huì)退到之前的frame屿储,不知道是否還有其他好的方法贿讹,有的話可以一起交流一下。

圖片剪裁部分

代碼如下:

-(void)cropImg
{
    CGRect cropFrame = self.cropView.frame;
    CGFloat orgX = cropFrame.origin.x * (self.img.size.width / self.imgView.frame.size.width);
    CGFloat orgY = cropFrame.origin.y * (self.img.size.height / self.imgView.frame.size.height);
    CGFloat width = cropFrame.size.width * (self.img.size.width / self.imgView.frame.size.width);
    CGFloat height = cropFrame.size.height * (self.img.size.height / self.imgView.frame.size.height);
    CGRect cropRect = CGRectMake(orgX, orgY, width, height);
    CGImageRef imgRef = CGImageCreateWithImageInRect(self.img.CGImage, cropRect);
    
    CGFloat deviceScale = [UIScreen mainScreen].scale;
    UIGraphicsBeginImageContextWithOptions(cropFrame.size, 0, deviceScale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, cropFrame.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextDrawImage(context, CGRectMake(0, 0, cropFrame.size.width, cropFrame.size.height), imgRef);
    UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
    CGImageRelease(imgRef);
    UIGraphicsEndImageContext();
    
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library toolWriteImageToSavedPhotosAlbum:newImg.CGImage metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
        if(error)
        {
            JGLog(@"寫入出錯(cuò)");
        }
    } groupName:@"相冊(cè)名稱"];
}

這里要注意一點(diǎn)CGContextDrawImage這個(gè)函數(shù)的坐標(biāo)系和UIKIt的坐標(biāo)系上下顛倒够掠,需對(duì)坐標(biāo)系處理如下:

CGContextTranslateCTM(context, 0, cropFrame.size.height);
CGContextScaleCTM(context, 1, -1);

看看效果:

屏幕快照 2016-01-11 上午10.04.06.png

剪裁之后的圖片:

屏幕快照 2016-01-11 上午10.05.44.png

簡(jiǎn)單demo:https://github.com/jiangtaidi/CropImgDemo.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末民褂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赊堪,老刑警劉巖面殖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異哭廉,居然都是意外死亡脊僚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門群叶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吃挑,“玉大人,你說我怎么就攤上這事街立〔俺模” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵赎离,是天一觀的道長(zhǎng)逛犹。 經(jīng)常有香客問我,道長(zhǎng)梁剔,這世上最難降的妖魔是什么虽画? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮荣病,結(jié)果婚禮上码撰,老公的妹妹穿的比我還像新娘。我一直安慰自己个盆,他們只是感情好脖岛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著颊亮,像睡著了一般柴梆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上终惑,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天绍在,我揣著相機(jī)與錄音,去河邊找鬼雹有。 笑死偿渡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的件舵。 我是一名探鬼主播卸察,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铅祸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤临梗,失蹤者是張志新(化名)和其女友劉穎涡扼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盟庞,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吃沪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了什猖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片票彪。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖不狮,靈堂內(nèi)的尸體忽然破棺而出降铸,到底是詐尸還是另有隱情,我是刑警寧澤摇零,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布推掸,位于F島的核電站,受9級(jí)特大地震影響驻仅,放射性物質(zhì)發(fā)生泄漏谅畅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一噪服、第九天 我趴在偏房一處隱蔽的房頂上張望毡泻。 院中可真熱鬧,春花似錦粘优、人聲如沸仇味。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邪铲。三九已至,卻和暖如春无拗,著一層夾襖步出監(jiān)牢的瞬間带到,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工英染, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揽惹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓四康,卻偏偏與公主長(zhǎng)得像搪搏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闪金,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,117評(píng)論 25 707
  • 這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)裁剪框和圖片剪裁功能疯溺,具有一定的參考價(jià)值论颅,感興趣的小伙伴們可以參考一下圖片處...
    木馬不在轉(zhuǎn)閱讀 11,507評(píng)論 9 10
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件囱嫩、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評(píng)論 4 62
  • 恪守之前的四步驟便可掌握分析閱讀的第一步: what a book is about and to outline...
    無夜閱讀 177評(píng)論 0 0
  • 我喜歡陽(yáng)光恃疯, 因?yàn)橛鲆娔阍陉?yáng)光下; 我喜歡陽(yáng)光墨闲, 因?yàn)槟憔褪俏业年?yáng)光今妄。 為你買了一個(gè)本子, 在每頁(yè)都寫上你的名字鸳碧,...
    遠(yuǎn)方孤雁閱讀 244評(píng)論 0 3