图片裁剪/滤镜渲染

一、图片裁剪

//拖动手势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
- (void)handlePanGes:(PanGesRec *)panGes
{
    CGPoint translation = [panGes translationInView:self.imgView.superview];
    CGPoint movePoint = panGes.movedPoint;
     
    //判断开始滑动时的滑动对象:top、bottom、left、right
    if (panGes.state == GR_BEGIN) {
         
        //再次开始移动,shaView整体高亮
        [UIView animateWithDuration:0.5 animations:^{
            self.shaView.isSetShadow = NO;
        }];
         
        if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge+SHORT_LINE_LENGTH MaxX:self.clipAreaLayer.rightEdge-SHORT_LINE_LENGTH MinY:self.clipAreaLayer.topEdge-PANGR_OFFET MaxY:self.clipAreaLayer.topEdge+PANGR_OFFET]) {
            self.acGeView = CLIP_AREA_TOP;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge+SHORT_LINE_LENGTH MaxX:self.clipAreaLayer.rightEdge-SHORT_LINE_LENGTH MinY:self.clipAreaLayer.bottomEdge-PANGR_OFFET MaxY:self.clipAreaLayer.bottomEdge+PANGR_OFFET]) {
            self.acGeView = CLIP_AREA_BOTTOM;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge-PANGR_OFFET MaxX:self.clipAreaLayer.leftEdge+PANGR_OFFET MinY:self.clipAreaLayer.topEdge+SHORT_LINE_LENGTH MaxY:self.clipAreaLayer.bottomEdge-SHORT_LINE_LENGTH]) {
            self.acGeView = CLIP_AREA_LEFT;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.rightEdge-PANGR_OFFET MaxX:self.clipAreaLayer.rightEdge+PANGR_OFFET MinY:self.clipAreaLayer.topEdge+SHORT_LINE_LENGTH MaxY:self.clipAreaLayer.bottomEdge-SHORT_LINE_LENGTH]) {
            self.acGeView = CLIP_AREA_RIGHT;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge-PANGR_OFFET MaxX:self.clipAreaLayer.leftEdge+PANGR_OFFET MinY:self.clipAreaLayer.topEdge MaxY:self.clipAreaLayer.topEdge+SHORT_LINE_LENGTH] || [self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge MaxX:self.clipAreaLayer.leftEdge+SHORT_LINE_LENGTH MinY:self.clipAreaLayer.topEdge-PANGR_OFFET MaxY:self.clipAreaLayer.topEdge+PANGR_OFFET]){
            self.acGeView = CLIP_AREA_LT;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge-PANGR_OFFET MaxX:self.clipAreaLayer.leftEdge+PANGR_OFFET MinY:self.clipAreaLayer.bottomEdge-SHORT_LINE_LENGTH MaxY:self.clipAreaLayer.bottomEdge] || [self judgeGesRecInViewWithMinX:self.clipAreaLayer.leftEdge MaxX:self.clipAreaLayer.leftEdge+SHORT_LINE_LENGTH MinY:self.clipAreaLayer.bottomEdge-PANGR_OFFET MaxY:self.clipAreaLayer.bottomEdge+PANGR_OFFET]){
            self.acGeView = CLIP_AREA_LB;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.rightEdge-PANGR_OFFET MaxX:self.clipAreaLayer.rightEdge+PANGR_OFFET MinY:self.clipAreaLayer.topEdge MaxY:self.clipAreaLayer.topEdge+SHORT_LINE_LENGTH] || [self judgeGesRecInViewWithMinX:self.clipAreaLayer.rightEdge-SHORT_LINE_LENGTH MaxX:self.clipAreaLayer.rightEdge MinY:self.clipAreaLayer.topEdge-PANGR_OFFET MaxY:self.clipAreaLayer.topEdge+PANGR_OFFET]){
            self.acGeView = CLIP_AREA_RT;
        } else if ([self judgeGesRecInViewWithMinX:self.clipAreaLayer.rightEdge-PANGR_OFFET MaxX:self.clipAreaLayer.rightEdge+PANGR_OFFET MinY:self.clipAreaLayer.bottomEdge-SHORT_LINE_LENGTH MaxY:self.clipAreaLayer.bottomEdge] || [self judgeGesRecInViewWithMinX:self.clipAreaLayer.rightEdge-SHORT_LINE_LENGTH MaxX:self.clipAreaLayer.rightEdge MinY:self.clipAreaLayer.bottomEdge-PANGR_OFFET MaxY:self.clipAreaLayer.bottomEdge+PANGR_OFFET]){
            self.acGeView = CLIP_AREA_RB;
        } else {
            self.acGeView = IMAGE_VIEW;
            [self.imgView setCenter:CGPointMake(self.imgView.center.x+translation.x, self.imgView.center.y+translation.y)];
            [panGes setTranslation:CGPointZero inView:self.imgView.superview];
        }
    }
     
     
    //滑动过程中位置改变
    CGFloat offsetX = 0;
    CGFloat offsetY = 0;
    if (panGes.state == GR_CHANGED) {
        switch (self.acGeView) {
            case CLIP_AREA_TOP:
            {
                offsetY = movePoint.y-self.clipAreaLayer.topEdge;
                 
                if (offsetY >=0 && self.clipAreaHeight >= CLIP_AREA_MIN_WH) {
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.topEdge += fabs(offsetY);
                } else if(offsetY < 0 && self.clipAreaLayer.topEdge >= CLIP_VIEW_TOP_MIN) {
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.topEdge -= fabs(offsetY);
                    [self scaleImgForTop];
                }
            }
                break;
            case CLIP_AREA_BOTTOM:
            {
                offsetY = movePoint.y-self.clipAreaLayer.bottomEdge;
                if (offsetY >= 0 && self.clipAreaLayer.bottomEdge <= SCREEN_HEIGHT-CLIP_VIEW_BOTTOM_MAX) {
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.bottomEdge += fabs(offsetY);
                    [self scaleImgForBottom];
                } else if (offsetY < 0 && self.clipAreaHeight >= CLIP_AREA_MIN_WH){
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.bottomEdge -= fabs(offsetY);
                }
            }
                break;
            case CLIP_AREA_LEFT:
            {
                offsetX = movePoint.x-self.clipAreaLayer.leftEdge;
                if (offsetX >= 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH) {
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaLayer.leftEdge += fabs(offsetX);
                }else if (offsetX < 0 && self.clipAreaLayer.leftEdge >= CLIP_VIEW_LR_MIN){
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaLayer.leftEdge -= fabs(offsetX);
                }
            }
                break;
            case CLIP_AREA_RIGHT:
            {
                offsetX = movePoint.x-self.clipAreaLayer.rightEdge;
                if (offsetX >= 0 && self.clipAreaLayer.rightEdge <= SCREEN_WIDTH-CLIP_VIEW_LR_MIN) {
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaLayer.rightEdge += fabs(offsetX);
                } else if (offsetX < 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH){
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaLayer.rightEdge -= fabs(offsetX);
                }
            }
                break;
            case CLIP_AREA_LT:
            {
                offsetX = movePoint.x-self.clipAreaLayer.leftEdge;
                offsetY = movePoint.y-self.clipAreaLayer.topEdge;
                if (offsetX >= 0 && offsetY >= 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH && self.clipAreaHeight >= CLIP_AREA_MIN_WH) {
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.leftEdge += fabs(offsetX);
                    self.clipAreaLayer.topEdge += fabs(offsetY);
                }else if (offsetX < 0 && offsetY < 0 && self.clipAreaLayer.leftEdge >= CLIP_VIEW_LR_MIN && self.clipAreaLayer.topEdge >= CLIP_VIEW_TOP_MIN){
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.leftEdge -= fabs(offsetX);
                    self.clipAreaLayer.topEdge -= fabs(offsetY);
                    [self scaleImgForTop];
                }
            }
                break;
            case CLIP_AREA_LB:
            {
                offsetX = movePoint.x-self.clipAreaLayer.leftEdge;
                offsetY = movePoint.y-self.clipAreaLayer.bottomEdge;
                if (offsetX >= 0 && offsetY <= 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH && self.clipAreaHeight >= CLIP_AREA_MIN_WH) {
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.leftEdge += fabs(offsetX);
                    self.clipAreaLayer.bottomEdge -= fabs(offsetY);
                }else if (offsetX < 0 && offsetY > 0 && self.clipAreaLayer.leftEdge >= CLIP_VIEW_LR_MIN && self.clipAreaLayer.bottomEdge <= SCREEN_HEIGHT-CLIP_VIEW_BOTTOM_MAX){
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.leftEdge -= fabs(offsetX);
                    self.clipAreaLayer.bottomEdge += fabs(offsetY);
                    [self scaleImgForBottom];
                }
            }
                break;
            case CLIP_AREA_RT:
            {
                offsetX = movePoint.x-self.clipAreaLayer.rightEdge;
                offsetY = movePoint.y-self.clipAreaLayer.topEdge;
                if (offsetX <= 0 && offsetY >= 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH && self.clipAreaHeight >= CLIP_AREA_MIN_WH) {
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.rightEdge -= fabs(offsetX);
                    self.clipAreaLayer.topEdge += fabs(offsetY);
                }else if (offsetX > 0 && offsetY < 0 && self.clipAreaLayer.rightEdge <= SCREEN_WIDTH-CLIP_VIEW_LR_MIN && self.clipAreaLayer.topEdge >= CLIP_VIEW_TOP_MIN){
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.rightEdge += fabs(offsetX);
                    self.clipAreaLayer.topEdge -= fabs(offsetY);
                    [self scaleImgForTop];
                }
            }
                break;
            case CLIP_AREA_RB:
            {
                offsetX = movePoint.x-self.clipAreaLayer.rightEdge;
                offsetY = movePoint.y-self.clipAreaLayer.bottomEdge;
                if (offsetX <= 0 && offsetY <= 0 && self.clipAreaWidth >= CLIP_AREA_MIN_WH && self.clipAreaHeight >= CLIP_AREA_MIN_WH) {
                    self.clipAreaWidth -= fabs(offsetX);
                    self.clipAreaHeight -= fabs(offsetY);
                    self.clipAreaLayer.rightEdge -= fabs(offsetX);
                    self.clipAreaLayer.bottomEdge -= fabs(offsetY);
                }else if (offsetX > 0 && offsetY > 0 && self.clipAreaLayer.rightEdge <= SCREEN_WIDTH-CLIP_VIEW_LR_MIN && self.clipAreaLayer.bottomEdge <= SCREEN_HEIGHT-CLIP_VIEW_BOTTOM_MAX){
                    self.clipAreaWidth += fabs(offsetX);
                    self.clipAreaHeight += fabs(offsetY);
                    self.clipAreaLayer.rightEdge += fabs(offsetX);
                    self.clipAreaLayer.bottomEdge += fabs(offsetY);
                    [self scaleImgForBottom];
                }
            }
                break;
            case IMAGE_VIEW:
            {
                [self.imgView setCenter:CGPointMake(self.imgView.center.x + translation.x, self.imgView.center.y+translation.y)];
                [panGes setTranslation:CGPointZero inView:self.imgView.superview];
            }
                break;
            default:
                break;
        }
        if (self.acGeView != IMAGE_VIEW) {
            [self setUpClipLayer:NO];
        }
    }
     
     
    if (panGes.state == GR_ENDED) {
         
        if (self.acGeView == IMAGE_VIEW) {
            //修正imgView位置————必须铺满clipAreaLayer
            [UIView animateWithDuration:0.5 animations:^{
                if (CGRectGetMinY(self.imgView.frame)>self.clipAreaLayer.topEdge) {
                    self.imgView.frame = CGRectMake(CGRectGetMinX(self.imgView.frame), self.clipAreaLayer.topEdge, CGRectGetWidth(self.imgView.frame), CGRectGetHeight(self.imgView.frame));
                }
                 
                if (CGRectGetMaxY(self.imgView.frame)<self.clipAreaLayer.bottomEdge) {
                    self.imgView.frame = CGRectMake(CGRectGetMinX(self.imgView.frame), self.clipAreaLayer.bottomEdge-CGRectGetHeight(self.imgView.frame), CGRectGetWidth(self.imgView.frame), CGRectGetHeight(self.imgView.frame));
                }
                 
                if (CGRectGetMinX(self.imgView.frame)>self.clipAreaLayer.leftEdge) {
                    self.imgView.frame = CGRectMake(self.clipAreaLayer.leftEdge, CGRectGetMinY(self.imgView.frame), CGRectGetWidth(self.imgView.frame), CGRectGetHeight(self.imgView.frame));
                }
                 
                if (CGRectGetMaxX(self.imgView.frame)<self.clipAreaLayer.rightEdge) {
                    self.imgView.frame = CGRectMake(self.clipAreaLayer.rightEdge-CGRectGetWidth(self.imgView.frame), CGRectGetMinY(self.imgView.frame), CGRectGetWidth(self.imgView.frame), CGRectGetHeight(self.imgView.frame));
                }
            }];
        }else{
             
            /*
             思路:滑动结束后位置修正
             1.clipAreaLayer的移动后会回到中心点和宽都固定的位置;
             2.clipAreaLayer的缩放:宽固定——如果高度超过最大值——固定高度为最大值——再确定宽度;
             3.imgView的缩放:根据clipAreaLayer的缩放比例来确定宽高;
             4.imgView的位置:以clipAreaLayer为基准并根据缩放前的上边和左边的相对位置的缩放量,来确定;
             */
             
            [NSThread sleepForTimeInterval:0.3];
            //        [self animationForPosition];//移动动画效果——待解决
             
            [UIView animateWithDuration:ANI_DURA animations:^{
                 
                //修正裁剪框之前的参照数据
                CGFloat preDrawClipTop = self.clipAreaLayer.topEdge;
                CGFloat preDrawClipLeft = self.clipAreaLayer.leftEdge;
                 
                //修正裁剪框
                CGFloat scale = [self drawClipArea];
                 
                //设置imgView————不能单纯靠裁剪框的位置偏移量来定位,要考虑到缩放
                CGFloat imgViewX = 0;
                CGFloat imgViewY = 0;
                CGFloat imgWidth = CGRectGetWidth(self.imgView.frame)*scale;
                CGFloat imgHeight = CGRectGetHeight(self.imgView.frame)*scale;
                 
                CGFloat offsetX = fabs(CGRectGetMinX(self.imgView.frame)-preDrawClipLeft);
                CGFloat offsetY = fabs(CGRectGetMinY(self.imgView.frame)-preDrawClipTop);
                imgViewX = self.clipAreaLayer.leftEdge-offsetX*scale;
                imgViewY = self.clipAreaLayer.topEdge-offsetY*scale;
                 
                self.imgView.frame = CGRectMake(imgViewX, imgViewY, imgWidth, imgHeight);
            }];
             
            //记录每次修复后的位置
            self.preClipAreaFrame = CGRectMake(self.clipAreaLayer.leftEdge, self.clipAreaLayer.topEdge, self.clipAreaWidth, self.clipAreaHeight);
        }
         
        //滑动后,超出clipAreaLayer的图片设置为透明
        [self configShadowArea];
    }
}

  //捏合手势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- (void)handlePinGes:(UIPinchGestureRecognizer *)pinGes
{
    CGPoint pinchCenter = [pinGes locationInView:self.imgView.superview];
     
    if (pinGes.state == UIGestureRecognizerStateBegan || pinGes.state == UIGestureRecognizerStateChanged) {
         
        [UIView animateWithDuration:0.5 animations:^{
            self.shaView.isSetShadow = NO;
        }];
         
        //CGAffineTransformScale方法90度旋转有问题
//        self.imgView.transform=CGAffineTransformScale(self.imgView.transform, pinGes.scale, pinGes.scale);
//        pinGes.scale = 1;
         
        CGFloat scale = pinGes.scale;
        CGFloat distanceX = self.imgView.frame.origin.x - pinchCenter.x;
        CGFloat distanceY = self.imgView.frame.origin.y - pinchCenter.y;
        CGFloat scaledDistanceX = distanceX * scale;
        CGFloat scaledDistanceY = distanceY * scale;
        CGRect newFrame = CGRectMake(self.imgView.frame.origin.x + scaledDistanceX - distanceX, self.imgView.frame.origin.y + scaledDistanceY - distanceY, self.imgView.frame.size.width * scale, self.imgView.frame.size.height * scale);
        self.imgView.frame = newFrame;
        pinGes.scale = 1;
    }
     
//    if (pinGes.state == UIGestureRecognizerStateEnded) {
     
        //不能过小
        if (CGRectGetMinY(self.imgView.frame)>self.clipAreaLayer.topEdge || CGRectGetMaxY(self.imgView.frame)<self.clipAreaLayer.bottomEdge || CGRectGetMinX(self.imgView.frame)>self.clipAreaLayer.leftEdge || CGRectGetMaxX(self.imgView.frame)<self.clipAreaLayer.rightEdge) {
            self.imgView.frame = CGRectMake(self.clipAreaLayer.leftEdge, self.clipAreaLayer.topEdge, self.clipAreaWidth, self.clipAreaHeight);
        }
         
        //不能过大
        CGFloat scaleNum = 10;
        CGFloat originalImgViewWidth = CGRectGetWidth(_originalImgViewFrame);
        if (CGRectGetWidth(self.imgView.frame)/originalImgViewWidth>scaleNum) {
            self.imgView.frame = _originalImgViewFrame;
            CGFloat distanceX = self.imgView.frame.origin.x - pinchCenter.x;
            CGFloat distanceY = self.imgView.frame.origin.y - pinchCenter.y;
            CGFloat scaledDistanceX = distanceX * scaleNum;
            CGFloat scaledDistanceY = distanceY * scaleNum;
            CGRect newFrame = CGRectMake(self.imgView.frame.origin.x + scaledDistanceX - distanceX, self.imgView.frame.origin.y + scaledDistanceY - distanceY, self.imgView.frame.size.width * scaleNum, self.imgView.frame.size.height * scaleNum);
            self.imgView.frame = newFrame;
            pinGes.scale = 1;
        }
     
//        NSLog(@"self.imgView.frame-----scale------%@", NSStringFromCGRect(self.imgView.frame));
//    }
     
    //缩放完后,需要点击一下图片才会执行该if语句————如何自动执行,待解决
    if (pinGes.state == UIGestureRecognizerStateEnded) {
        [self configShadowArea];
    }
//    self.resetBtn.hidden = NO;
}

//旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
case 301://旋转90度——顺时针
        {
            _rorateNum++;
             
            [UIView animateWithDuration:0.5 animations:^{
                self.shaView.isSetShadow = NO;
            }];
            self.clipAreaLayer.hidden = YES;
            CGFloat dura = 1.0f;
             
            //旋转前:记录imgView与clipAreaLayer左边和底边的距离
            CGFloat preRoOffsetX = fabs(CGRectGetMaxY(self.imgView.frame)-self.clipAreaLayer.bottomEdge);
            CGFloat preRoOffsetY = fabs(CGRectGetMinX(self.imgView.frame)-self.clipAreaLayer.leftEdge);
             
            //旋转
            [UIView animateWithDuration:dura animations:^{
                CGAffineTransform trans = CGAffineTransformMakeRotation(_valueOffset);
                self.imgView.transform = trans;
            }];
             
            _valueOffset += M_PI_2;
            if (_rorateNum == kRotateNumMax) {
                _valueOffset = M_PI_2;
                _rorateNum = 0;
            }
             
            //切换坐标——imgView的frame自动修正
            [self changeXYWithRotation:_valueOffset];
            UIImage *agerImage = [self getRotatedImg];
            self.targetImg = agerImage;
             
            CGFloat temp = self.clipAreaWidth;
            self.clipAreaWidth = self.clipAreaHeight;
            self.clipAreaHeight = temp;
            CGFloat scale = [self drawClipArea];
//            [self setUpClipLayer:YES];
             
            //旋转后:调整imgView的位置——左变上,底变左
            self.imgView.frame = CGRectMake(self.clipAreaLayer.leftEdge-preRoOffsetX, self.clipAreaLayer.topEdge-preRoOffsetY, CGRectGetWidth(self.imgView.frame), CGRectGetHeight(self.imgView.frame));
             
            //缩放
            CABasicAnimation *baAniScale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            baAniScale.beginTime = dura;
            baAniScale.duration = dura;
            baAniScale.fromValue = @1;
            baAniScale.toValue = @(scale);
            [self.imgView.layer addAnimation:baAniScale forKey:nil];
             
            //缩放后调整imgView的位置
            CGFloat imgViewX = 0;
            CGFloat imgViewY = 0;
            CGFloat imgWidth = CGRectGetWidth(self.imgView.frame)*scale;
            CGFloat imgHeight = CGRectGetHeight(self.imgView.frame)*scale;
 
            imgViewX = self.clipAreaLayer.leftEdge-preRoOffsetX*scale;
            imgViewY = self.clipAreaLayer.topEdge-preRoOffsetY*scale;
             
            //修正imgView位置
            self.imgView.frame = CGRectMake(imgViewX, imgViewY, imgWidth, imgHeight);
             
            //修正clipAreaLayer位置
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                self.clipAreaLayer.hidden = NO;
            });
             
            [self configShadowArea];
        }

  //裁剪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//要的是实际图片的大小
- (UIImage *)clipDownOriginalImg
{
    CGFloat imageScale = MIN(self.imgView.frame.size.width/self.targetImg.size.width, self.imgView.frame.size.height/self.targetImg.size.height);
    CGFloat clipX = (self.clipAreaLayer.leftEdge - self.imgView.frame.origin.x)/imageScale;
    CGFloat clipY = (self.clipAreaLayer.topEdge - self.imgView.frame.origin.y)/imageScale;
    CGFloat clipWidth = self.clipAreaWidth/imageScale;
    CGFloat clipHeight = self.clipAreaHeight/imageScale;
    CGRect clipImgRect = CGRectMake(clipX, clipY, clipWidth, clipHeight);
     
    CGImageRef sourceImageRef = [self.targetImg CGImage];
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, clipImgRect);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    CGImageRelease(newImageRef);
     
    return newImage;
}

  

二、滤镜——主要用到GPUImage框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- (void)colorImg:(UIImage *)img
{
    [self.filter forceProcessingAtSize:img.size];
    self.staticPicture.image = img;
     
    if (self.outPutImgArr.count > 0) {
        [self.outPutImgArr removeAllObjects];
    }
     
    //图片太多,内存爆增,系统会自动杀掉app
//    [self.outPutImgArr addObject:img];
//    NSArray *paramArr = @[@"0.1", @"0.2", @"0.3", @"0.4", @"0.5", @"0.6", @"0.7", @"0.8", @"0.9", @"1.0"];
    NSArray *paramArr = @[@"0.3", @"0.5", @"0.7", @"0.9", @"1.0"];
     
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
 
        dispatch_apply(paramArr.count, queue, ^(size_t index) {
 
            NSString *paramStr = paramArr[index];
            [self.filter setIntensity: paramStr.floatValue];
            [self.staticPicture processImage];
            [self.outPutImgArr addObject:[self.filter imageFromCurrentlyProcessedOutput]];
             
//            NSLog(@"memoryUsage------%lld", [self memoryUsage]);
 
            dispatch_async(dispatch_get_main_queue(), ^{
                [self reloadData];
            });
        });
         
//        NSLog(@"-------Done1");
         
    });
     
//    NSLog(@"-------Done2");
     
}

  

三、效果图

 

 

GitHub地址

posted @   春天里的花骨朵  阅读(350)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示