当前位置:秋叶网络博客 前端设计 ◊ Canvas裁剪等比尺寸文章缩略图

Canvas裁剪等比尺寸文章缩略图

作者:秋叶 发表时间:2017年3月11日

通常来说,缩略图都是读取文章里面的一张大图片再通过css缩小显示,或者是后台经过处理后生成的另外一张对应的图片,这里不做讨论,我们是前端就得用前端的方法。然而图片大小不一会给前端响应式造成巨大的麻烦,关于响应式固定宽高比例前面一篇文章已经讲过一种方法《纯css自适应div高度(等比缩放)》,今天讲另外一种更高级的canvas办法。除了固定宽高比例,还实现了裁剪中心位置像素。然后用canvas代替img标签放于网页img原先位置或者输出dataurl形式的img地址。

原理是:页面默认不显示图片,把图片的src地址绑定到data-src上,注意一定要在同一个服务器的图片(本地也不行),然后通过js取到这个图片,内存中进行加载,加载完成,计算图片的裁剪宽高区域,然后生成一个canvas,把相应区域的图像绘制到canvas上,再把canvas插到页面中。


  • 这是第一张图片裁剪后
  • 这是第二张图片裁剪后
  • 这是第三张图片裁剪后
  • 这是默认图片裁剪后

参考html:

<div id="container">
   <img data-src="3.png" id="img" />
</div>

参考js:

function cutImg(imgsrc,width,height,container,bgColor){
	var count=0;
	var defaultImg="/thumb/New_Project_copy-3069f937ed77449b8bf4b046d211b62a.png";//加载错误默认显示的图片
	var img=document.createElement("img");
	    img.src=imgsrc;
	var cvs=document.createElement("canvas");
	    cvs.width=width;
	    cvs.height=height;
	var context=cvs.getContext('2d');
	    context.fillStyle=bgColor;
	    context.rect(0,0,width,height);
	    context.fill();
	    appendCvs(container);
	function appendCvs(container){
	    if(typeof container == "object"){
	        container.html("").append(cvs);
	    }else{
	        var _container=document.querySelector(container);
	        _container.innerHTML="";
	        _container.appendChild(cvs);
	    }
	}
	var rate=width/height;
	img.onload=function(){
	    var imgWidth=img.width,imgHeight=img.height;
	    var rate=imgWidth/imgHeight;
	    var dx,dy,sx,sy,cvsw=width,cvsh=height,cvsx=0,cvsy=0;
	    if(imgWidth <= width && imgHeight <= height){//宽高都小于canvas尺寸
  		dx=imgWidth,dy=imgHeight;
  		sx=0,sy=0;
  		if(rate > 1){
                    cvsw=width,cvsh=cvsw/rate;
		    cvsx=0,cvsy=(height-cvsh)/2;
		}else{
		    cvsh=height,cvsw=cvsh*rate;
		    cvsy=0,cvsx=(width-cvsw)/2;
		}			
	    }else if(rate < 1){//宽度小于高度时
		dx=imgWidth,dy=dx;
		sx=0,sy=(imgHeight-dy)/2;
	    }else{//高度小于宽度时
		dx=imgHeight,dy=dx;
		sx=(imgWidth-dx)/2,sy=0;
	    }
	    context.drawImage(img, sx, sy, dx, dy, cvsx, cvsy, cvsw, cvsh);
	    //var dataImg=cvs.toDataURL("image/jpeg");
	    appendCvs(container);
	} 
	img.onerror=function(){
	    count++;//防止图片一直加载不出来造成死循环
	    (count < 2) && cutImg(defaultImg,width,height,container,bgColor);
	}
}

调用方式:

cutImg($("#img").attr("data-src"),200,200,"#container","#fff");
//五个参数,第一个是要截取的源图片,第二个是canvas宽,第三个是高,第四个是最终放图片的容器,注意这个容器会被清空,第五个是canvas背景颜色。

//往往会批量处理一组缩略图,只需要重复调用这个函数即可:
$("#container .card").each(function(index,ele){
	var imgSrc=$(ele).find("img").attr("src");
	cutImg(imgSrc,200,200,$(ele).find(".card"),"#fff");
});

忘了说css,css很简单,设置canvas的宽度为100%即可,高度会按你设置的canvas宽高比例缩放。

目录: 前端设计 | 标签: | 5542次阅读