zoukankan      html  css  js  c++  java
  • 一个图片裁剪控件

    这篇文章就是介绍开篇说的图片裁剪视图的构建。

          

      效果图如上图所示. 要求:

    1. 裁剪框是正方形, 要求保持位置, 大小不变.
    2. 底图可以放大, 缩小,旋转.
    3. 底图在缩小时, 无论怎么缩小. 都要保持最小边不能超过正方形的边长. 即不能出现黑边. 要保持图片始终能够填充正方形.
    4. 当图片大于正方形时, 底图能随意左右上下滑动. 使边缘能够与正方形对齐.

       首先, 初步分析需求. 缩放操作可以利用ScollView的Zoom属性来实现. 旋转可以利用UIView的TransForm来实现. 感觉很简单. 确实. 

      但是, 怎么拼合这3个视图的关系, 才能在进行缩放, 拖动的时候知道选择区与ImageView的相对坐标呢? 以此我们通过DrawInRect函数正确输出选择的图片?

      View Hierarchy:

      

      

      经过一番分析和实验, (这里忽略了如何解决这个问题的过程, 因为写起来很复杂.)最终可以实现的方法如下:

    • UIScrollView:
      • 大小与选择区保持一致  (这样我们不需要设置ContentInset属性来满足需求4, 因为在缩放的过程中ContentInset会影响最终位置的计算)
      • clipsToBounds属性改为NO (UIScrollView默认为YES, 这个是关键)
      • 设置ContentSize大小为UIImageView的宽和高. (这样可以满足需求4)
      • 设置ContentOffset, 使UIImageView初始在居中位置
      • 设置最小缩放比例为1, 最大缩放比例为3(可以随意设置).
    • UIImageView:
      • 长宽比与图片保持一致, 且最小边与选择区的边长保持一致. 

      以上这样做的好处就是, 直接利用ScrollView的ContentOffset属性就可以轻易的知道选择区在图片上的相对位置. 如下.

    CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height);

      整个裁剪的代码:

        UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 320), 1, 1);
        CGRect drawRect = CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height);
        [origionImage drawInRect:drawRect];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

      一目了然, 相当简便, 省去了诸多宽高的反复计算. 也不用来回倒腾UIImageView和ScrollView的几何属性.

      对于需求2的旋转操作. 每当进行一次旋转的时候, 我们只是让ScrollView(而不是ImageView)进行旋转, 如下:

    - (void)rotateClockWise90Degree
    {
        _rotateCounter++;
        [_scrollView setZoomScale:1.f];
        
        CGAffineTransform rotateTranform = CGAffineTransformRotate(_scrollView.transform, M_PI_2);
        [UIView animateWithDuration:.25f animations:^{
            _scrollView.transform = rotateTranform;
        }];
    }

      旋转后的裁剪, 我们依然使用前面的裁剪代码. 这样裁剪的坐标系始终是ScrollView的坐标系. 然后我们图像做一次旋转, 这里有个技巧, 我们不需设置绘制Context的Transfrom, 并对Image进行重新DrawRect. 我们可以调用系统的一个函数, 一段语句完成这个操作, 如下.

    image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation];

      非常简单. 当然orientation参数是通过旋转次数计算出来的.

      这样所有的操作最终简练成2段语句

    CGRect drawRect = CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height);
    
    与
    
    image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation];

      

      所以, 只要提前设计好了需求的实现, 代码写起来也是想当的方便易懂.

      代码下载地址: DownLoad

  • 相关阅读:
    饱和色
    Server.MapPath()相关
    Oracle修改表结构
    远程关机
    使用sqlplus创建表空间
    自写Js+CSS轮显效果
    右下角随机显示的CSS+JS图片广告
    JavaScript实现鼠标放上动画加载大图的代码
    CSS实现自适应的图片背景边框代码
    JavaScript弹性透明的图片放大代码
  • 原文地址:https://www.cnblogs.com/JohnDeBlog/p/3546710.html
Copyright © 2011-2022 走看看