iOS图片延迟解压上海时时乐走势图官网

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>jQuery之家</title>
    <style type="text/css">
        *{margin:0;padding:0;}
        body{font-size: 14px;}
        canvas{
            display:none;
            background-color: #ffff91;
        }
        #square{
            width:80px;
            height: 80px;
            background-color: rgba(117,240,255,0.5);
            position:absolute;
            z-index: 999;
            cursor:crosshair;
            display:none;
        }
    </style>
    <script>
        onload=function(){
            var canvas=document.getElementById("canvas");//获取画布
            var ctx=canvas.getContext("2d");//获取画笔
            var img=document.getElementsByTagName("img")[0];//获取图片
            var square=document.getElementById("square");//获取选择框
            var squareData={};//存选择框信息
            var imgPosition=img.getBoundingClientRect();//获取图片的位置
            var p=img.naturalWidth/img.width;//原始图片与缩小后图片的比例
           // var even;
            //鼠标移入
            img.onmouseove=function(e){
                var even=e||event;//兼容火狐浏览器
                var x=even.clientX,
                    y=even.clientY;
                createSquare(x,y);
            };
            window.onmousemove=function(e){
                var even=e||event;
                var x=even.clientX;
                var y=even.clientY;
                //使选择框限制在图片内部
                if(x>=img.offsetLeft&&x<=img.offsetLeft img.width&&y>=img.offsetTop&&y<=img.offsetTop img.height){
                     createSquare(x,y);
                }else{
                    hideSquare();
                    hideCanvas();
                }
            };
            function createSquare(x,y){
                x=x-40<img.offsetLeft?img.offsetLeft:x-40;
                y=y-40<img.offsetTop?img.offsetTop:y-40;
                x=x 80<imgPosition.right?x:imgPosition.right-80;
                y=y 80<imgPosition.bottom?y:imgPosition.bottom-80;
                //将选择框左上角的位置存到squareData
                squareData.left=x;
                squareData.top=y;
                moveSquare(x,y);
            }
            function moveSquare(x,y){
                //设置选择框偏移位置
                square.style.left=x "px";
                square.style.top=y "px";
                showCanvas();
                showSquare();
                draw();
            }
            function showCanvas(){
                canvas.style.display="inline";
            }
            function hideCanvas(){
                canvas.style.display="none";
            }
            function showSquare(){
                square.style.display="inline";
            }
            function hideSquare(){
                square.style.display="none";
            }
            //将放大后的图片画到canvas中
            function draw(){
                console.log(squareData.left-imgPosition.left);
                ctx.drawImage(img,(squareData.left-imgPosition.left)*p,p*(squareData.top-imgPosition.top),p*80,p*80,0,0,canvas.width,canvas.height);
            }
        }
    </script>
</head>
<body>
<img src="img/N7ETzFO.jpg" alt="上海时时乐走势图官网 1" width="300px">
<canvas id="canvas" width="300px" height="225px"></canvas>
<div id="square"></div>
</body>
</html>

如果不适用 imageNamed:,那么把整张图片绘制到 CGContext 可能是最佳的方式了。尽管你可能认为多余的绘制相较别的解压技术而言性能不是很高,但是新创建的图片(在特定设备上做过的优化)可能比原始图片绘制的更快。

具体实现思路:

  • 1.假设边框宽度为BorderW
  • 2.开启的图片上下文的尺寸就应该是原始图片的宽高分别加上两倍的BorderW,这样开启的目的是为了不让原始图片变形.
  • 3.在上下文上面添加一个圆形填充路径.位置从(0,0)点开始,宽高和上下文尺寸一样大.设置颜色为要设置的边框颜色.
  • 4.继续在上下文上面添加一个圆形路径,这个路径为裁剪路径.
    它的x,y分别从BorderW这个点开始.宽度和高度分别和原始图片的宽高一样大.将绘制的这个路径设为裁剪区域.
  • 5.把原始路径绘制到上下文当中.绘制的位置和是裁剪区域的位置相同,x,y分别从border开始绘制.
  • 6.从上下文状态当中取出图片.
  • 7.关闭上下文状态.

图形参照:

上海时时乐走势图官网 2

3.gif

canvas 绘制图片是根据原始图片的尺寸进行绘制,而不是根据利用属性或样式放大缩小后的图片,所以要乘以原始图片与现在图片的比例。

有两种方式可以强制解压提前渲染图片:
1、将图片的一个像素绘制成一个像素大小的 CGContext。这样仍然会解压整张图片,但是绘制本身并没有消耗任何时间。这样的好处在于加载的图片并不会在特定的设备上为绘制做优化,所以可以在任何时间点绘制出来。同样iOS也就可以丢弃解压后的图片来节省内存了。
2、将整张图片绘制到 CGContext 中,丢弃原始的图片,并且用一个从上下文内容中新的图片来代替。这样比绘制单一像素那样需要更加复杂的计算,但是因此产生的图片将会为绘制做优化,而且由于原始压缩图片被抛弃了,iOS就不能够随时丢弃任何解压后的来节省内存了。

加载要裁剪的图片

UIImage *image = [UIImage imageNamed:@"阿狸头像"];

  • 0.设置边框大小.
    CGFloat borderW = 10;
  • 1.开启一个和原始图片一样大小的位图上下文.
UIGraphicsBeginImageContextWithOptions(size,NO,0);```
 -  2.绘制一个大圆,填充
``` UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];    
[[UIColor blueColor] set];
[path fill];```
 -   3.添加一个裁剪区域.
```path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderW, borderW, image.size.width, image.size.height)];
[path addClip];```
 -   4.把图片绘制到裁剪区域当中.
 ```[image drawAtPoint:CGPointMake(borderW, borderW)];```
 -   5.生成一张新图片.
```UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();```
 -   6.关闭上下文.
 ```UIGraphicsEndImageContext();```

######抽取分类方法:

```根据传入的图片,生成一终带有边框的圆形图片.
borderW边框宽度
borderColor:边框颜色
image:要生成的原始图片.
  (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image;

  (UIImage *)imageWithBorderW:(CGFloat)borderW borderColor:(UIColor *)color image:(UIImage *)image;```
  - 1.开启一个和原始图片一样大小的位图上下文.
```CGSize size = CGSizeMake(image.size.width   2 *borderW, image.size.height   2 * borderW);
UIGraphicsBeginImageContextWithOptions(size,NO,0);```
  -  2.绘制一个大圆,填充
```UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];   
[[UIColor blueColor] set];
[path fill];```
  -  3.添加一个裁剪区域.
```path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderW, borderW, image.size.width, image.size.height)];
[path addClip];```
  -  4.把图片绘制到裁剪区域当中.
```[image drawAtPoint:CGPointMake(borderW, borderW)];```
  -  5.生成一张新图片.
```UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();```
  -  6.关闭上下文.
```UIGraphicsEndImageContext();       return clipImage;```
 iOS一旦图片文件被加载就必须要进行解码,解码过程是一个相当复杂的任务,需要消耗非常长的时间。解码后的图片将同样使用相当大的内存。
 用于加载的CPU时间相对于解码来说根据图片格式而不同。对于PNG图片来说,加载会比JPEG更长,因为文件可能更大,但是解码会相对较快,而且Xcode会把PNG图片进行解码优化后引入工程。JPEG图片更小,加载更快,但是解压的步骤需要更长的时间,因为JPEG解压算法比基于zip的PNG算法更加复杂。
当加载图片的时候,iOS通常会延迟解压图片的时间,直到加载到内存之后。这就会在准别绘制图片的时候影响性能,因为需要在绘制之前需要解压(通常是消耗时间的问题所在)。
最简单的方法就是使用 UIImage 的  imageNamed:方法避免延时加载。不像  imageWithContentOfFile:(和其他别的 UIImage 加载方法),这个方法会在加载图片之后立刻解压。问题是  imageNamed:只对从应用资源中的图片有效,所以对用户生成的图片内容或者是下载的图片就没法使用了。
另一种立刻加载图片的方法就是把他设置成图层内容,或者是 UIIMageView 的 image 属性。不幸的是,这又需要在主线程执行,所以不会对性能有所提升。
第三种方式就是绕过 UIKit,使用 ImageIO框架。
最后一种方式就是使用UIKit加载图片,但是立刻会知道 CGContext 中去。图片必须要在绘制之前解压,所以就强制了解压的及时性。这样的好处在于绘制图片可以在后台线程(例如加载本身)执行,而不会阻塞UI。

同样,如果想显示图片到比原始尺寸小的容器中,那么一次性在后台线程重新绘制到正确的尺寸会比每次显示的时候都做缩放会更有效。

需要注意的是苹果特别推荐了不要使用这些诡计拉绕过标准图片解压逻辑(所以也是他们选择用默认处理方式的原因),但是如果你使用很多大图来构建应用,那如果想提升性能,就只能和系统博弈了。

本文由上海时时乐走势图发布于web前端,转载请注明出处:iOS图片延迟解压上海时时乐走势图官网

您可能还会对下面的文章感兴趣: