适应各浏览器图片裁剪无刷新上传js插件

来源:互联网 发布:mac dts 转 wav 编辑:程序博客网 时间:2024/05/22 03:31
很多时候在项目中需要用到将图片的其中一部分裁剪后再使用的功能,比如像上传个人头像什么的!用户上传一张大图,但是需要裁剪其中的一块作为头像,我看到很多地方都采用了flash的方式,当然使用flash是不错的,不过我更倾向于使用javascript来解决这个问题,诚然这样的js插件也很多,不过这些插件都有一个通病就是仅仅做了对图片的裁剪数据采样,并没有无刷新上传的功能,并且需要上传图片后,再开始预览裁剪(本来想自己写一个,但是看到那么多现成的插件,也就懒散了  呵呵^_^)。
那么问题就来了,能不能把无刷新上传以及本地预览的功能与图片裁剪数据采样的功能统一起来喃!当然是可以的,这次这个插件就是解决这个问题的,这样做的好处是显而易见的,选择图片后就能本地预览无需上传即可开始选择需要裁剪的部分,一旦选中了需裁剪的部分,只需上传一次就搞定了。

我们如何开始喃?首先我们先确定使用那个图片裁剪数据采集插件,我选择了Jcrop(后面会给出下载地址),感觉这个插件做得不错,那么下一步就是再自己写一个插件来包装这个插件,也就是说上传部分由我们自己来实现,然后在其中嵌入Jcrop,这样就同时达到了无刷新上传并裁剪图片的目的,老规矩还是先上个效果图吧!

怎么样?看着还不错吧!操作也很简单,只需选择图片,然后就可以设定你想截取的地方,最后点击“上传截图”按钮就OK了
再来看看如何使用,同样首先建立如下的一个page

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    <title></title>    <link href="tapmodo-Jcrop-1902fbc/css/jquery.Jcrop.min.css" rel="stylesheet" />    <script src="Scripts/jquery-1.7.1.min.js"></script>    <script src="tapmodo-Jcrop-1902fbc/js/jquery.Jcrop.min.js"></script>    <script src="imageCropperUpload.js"></script>    <script>        $(function () {            var btn = $("#Button1");            btn.cropperUpload({                url: "WebForm1.aspx",                fileSuffixs: ["jpg", "png", "bmp"],                errorText: "{0}",                onComplete: function (msg) {                    $("#testimg").attr("src", msg);                },                cropperParam: {//Jcrop参数设置,除onChange和onSelect不要使用,其他属性都可用                    maxSize: [100, 100],//不要小于50,如maxSize:[40,24]                    minSize: [70, 70],//不要小于50,如minSize:[40,24]                    bgColor: "black",                    bgOpacity: .4,                    allowResize: false,                    allowSelect: false,                    animationDelay:50                },                perviewImageElementId: "fileList", //设置预览图片的元素id                  perviewImgStyle: { width: '700px', height: '500px', border: '1px solid #ebebeb' }//设置预览图片的样式              });            var upload = btn.data("uploadFileData");            $("#files").click(function () {                upload.submitUpload();            });        });    </script></head><body>    <div style="width: 400px; height: 300px; float:left">              <input id="Button1" type="button" value="选择文件" />              <input id="files" type="button" value="上传截图" />              <div id="fileList" style="margin-top: 10px; padding-top:10px; border-top:1px solid #C0C0C0;font-size: 13px; width:400px">                                </div>      </div>         <div id="testdiv" style="padding-top: 580px">        <img alt="" src="" id="testimg"/>    </div> </body></html>

我来说明一下以下这几个引用文件的关系

    <link href="tapmodo-Jcrop-1902fbc/css/jquery.Jcrop.min.css" rel="stylesheet" />    <script src="Scripts/jquery-1.7.1.min.js"></script>    <script src="tapmodo-Jcrop-1902fbc/js/jquery.Jcrop.min.js"></script>    <script src="imageCropperUpload.js"></script>

其中jquery.Jcrop.min.css和jquery.Jcrop.min.js是Jcrop插件必须的一个样式表文件和js文件,当然jquery是一定要引入的,最后面的imageCropperUpload.js文件就是自己写的插件,注意引用顺序不要弄错了,否则不起作用,上面示例中的代码我就不说了,都是很简单的设置,如果还有什么不清楚,欢迎留言,我会解答。

下面是插件源码(注意:这个是我写的插件,使用的时候把它copy下来保存为imageCropperUpload.js,就可以在页面上引用了)

(function ($) {    var defaultSettings = {        url: "",                                 //上传地址          fileSuffixs: ["jpg", "png"],             //允许上传的文件后缀名列表          errorText: "不能上传后缀为 {0} 的文件!", //错误提示文本,其中{0}将会被上传文件的后缀名替换          onCheckUpload: function (text) { //上传时检查文件后缀名不包含在fileSuffixs属性中时触发的回调函数,(text为错误提示文本)          },        onComplete: function (msg) { //上传完成后的回调函数[不管成功或失败,它都将被触发](msg为服务端的返回字符串)             alert(msg);        },        onChosen: function (file, obj, fileSize, errorTxt) { /*选择文件后的回调函数,(file为选中文件的本地路径;obj为当前的上传控件实例,                                                                    fileSize为上传文件大小,单位KB[只有在isFileSize为true时,此参数才有值],                                                                     errorTxt为获取文件大小时的错误文本提示)  */            //alert(file);          },        cropperParam: {}, //图片截取参数设置,此参数即为Jcrop插件参数        isFileSize: false,//是否获取文件大小        perviewImageElementId: "",//用于预览上传图片的元素id(请传入一个div元素的id)          perviewImgStyle: null//用于设置图片预览时的样式(可不设置,在不设置的情况下多文件上传时只能显示一张图片),如{ width: '100px', height: '100px', border: '1px solid #ebebeb' }      };    $.fn.cropperUpload = function (settings) {        settings = $.extend({}, defaultSettings, settings || {});        return this.each(function () {            var self = $(this);            var upload = new UploadAssist(settings);            upload.createIframe(this);            //绑定当前按钮点击事件              self.bind("click", function (e) {                upload.chooseFile();            });            //将上传辅助类的实例,存放到当前对象中,方便外部获取              self.data("uploadFileData", upload);            //创建的iframe中的那个iframe,它的事件需要延迟绑定              window.setTimeout(function () {                $(upload.getIframeContentDocument().body).find("input[type='file']").change(function () {                    if(!this.value) return;                    var fileSuf = this.value.substring(this.value.lastIndexOf(".") + 1);                    //检查是否为允许上传的文件                      if (!upload.checkFileIsUpload(fileSuf, upload.settings.fileSuffixs)) {                        upload.settings.onCheckUpload(upload.settings.errorText.replace("{0}", fileSuf));                        return;                    }                    if (upload.settings.isFileSize) {                        var size = perviewImage.getFileSize(this, upload.getIframeContentDocument());                        var fileSize, errorTxt;                        if (size == "error") {                            errorTxt = upload.errorText;                        } else {                            fileSize = size;                        }                        //选中后的回调                          upload.settings.onChosen(this.value, this, fileSize, errorTxt);                    } else {                        //选中后的回调                          upload.settings.onChosen(this.value, this);                    }                    //是否开启了图片预览                      if (upload.settings.perviewImageElementId) {                        var main = perviewImage.createPreviewElement("closeImg", this.value, upload.settings.perviewImgStyle);                        $("#" + upload.settings.perviewImageElementId).append(main);                        var div = $(main).children("div").get(0);                        perviewImage.beginPerview(this, div, upload.getIframeContentDocument(), upload);                    }                });                //为创建的iframe内部的iframe绑定load事件                  $(upload.getIframeContentDocument().body.lastChild).on("load", function () {                    var dcmt = upload.getInsideIframeContentDocument();                    upload.submitStatus = true;                    if (dcmt.body.innerHTML) {                        if (settings.onComplete) {                            settings.onComplete(dcmt.body.innerHTML);                        }                        dcmt.body.innerHTML = "";                    }                });            }, 100);        });    };})(jQuery);//上传辅助类function UploadAssist(settings) {    //保存设置    this.settings = settings;    //创建的iframe唯一名称    this.iframeName = "upload" + this.getTimestamp();    //提交状态    this.submitStatus = true;    //针对IE上传获取文件大小时的错误提示文本    this.errorText = "请设置浏览器一些参数后再上传文件,方法如下(设置一次即可):\n请依次点击浏览器菜单中的\n'工具->Internet选项->安全->可信站点->自定义级别'\n在弹出的自定义级别窗口中找到 'ActiveX控件和插件' 项,将下面的子项全部选为 '启用' 后,点击确定。\n此时不要关闭当前窗口,再点击 '站点' 按钮,在弹出的窗口中将下面复选框的 '√' 去掉,然后点击 '添加' 按钮并关闭当前窗口。\n最后一路 '确定' 完成并刷新当前页面。";    this.jcropApi;    return this;}UploadAssist.prototype = {    //辅助类构造器    constructor: UploadAssist,    //创建iframe    createIframe: function (/*插件中指定的dom对象*/elem) {        var html = "<html>"        + "<head>"        + "<title>upload</title>"        + "<script>"        + "function getDCMT(){return window.frames['dynamic_creation_upload_iframe'].document;}"        + "</" + "script>"        + "</head>"        + "<body>"        + "<form method='post' target='dynamic_creation_upload_iframe' enctype='multipart/form-data' action='" + this.settings.url + "'>"        + "<input type='text' id='x1' name='x1' />"        + "<input type='text' id='y1' name='y1' />"        + "<input type='text' id='x2' name='x2' />"        + "<input type='text' id='y2' name='y2' />"        + "<input type='text' id='w'  name='w' />"        + "<input type='text' id='h'  name='h' />"        + "<input type='text' id='maxW' name='maxW' />"        + "<input type='text' id='maxH' name='maxH' />"        + "<input type='file' name='fileUpload' />"        + "</form>"        + "<iframe name='dynamic_creation_upload_iframe'></iframe>"        + "</body>"        + "</html>";        this.iframe = $("<iframe name='" + this.iframeName + "'></iframe>")[0];        this.iframe.style.width = "0px";        this.iframe.style.height = "0px";        this.iframe.style.border = "0px solid #fff";        this.iframe.style.margin = "0px";        elem.parentNode.insertBefore(this.iframe, elem);        var iframeDocument = this.getIframeContentDocument();        iframeDocument.write(html);    },    //获取时间戳    getTimestamp: function () {        return (new Date()).valueOf();    },    //设置图片缩放的最大高宽    setMaxWidthAndHeight: function (/*最大宽*/maxW,/*最大高*/maxH) {        this.getElement("maxW").value = maxW;        this.getElement("maxH").value = maxH;    },    //设置图片截取参数    setImageCropperObj: function (/*图片截取对象*/obj) {        this.getElement("x1").value = obj.x;        this.getElement("y1").value = obj.y;        this.getElement("x2").value = obj.x2;        this.getElement("y2").value = obj.y2;        this.getElement("w").value = obj.w;        this.getElement("h").value = obj.h;    },    //获取创建的iframe中的元素    getElement: function (id) {        var dcmt = this.getIframeContentDocument();        return dcmt.getElementById(id);    },    //获取创建的iframe中的document对象    getIframeContentDocument: function () {        return this.iframe.contentDocument || this.iframe.contentWindow.document;    },    //获取创建的iframe所在的window对象    getIframeWindow: function () {        return this.iframe.contentWindow || this.iframe.contentDocument.parentWindow;    },    //获取创建的iframe内部iframe的document对象    getInsideIframeContentDocument: function () {        return this.getIframeWindow().getDCMT();    },    //获取上传input控件    getUploadInput: function () {        var inputs = this.getIframeContentDocument().getElementsByTagName("input");        var uploadControl;        this.forEach(inputs, function () {            if (this.type === "file") {                uploadControl = this;                return false;            }        });        return uploadControl;    },    //forEach迭代函数    forEach: function (/*数组*/arr, /*代理函数*/fn) {        var len = arr.length;        for (var i = 0; i < len; i++) {            var tmp = arr[i];            if (fn.call(tmp, i, tmp) == false) {                break;            }        }    },    //提交上传    submitUpload: function () {        if (!this.submitStatus) return;        this.submitStatus = false;        this.getIframeContentDocument().forms[0].submit();    },    //检查文件是否可以上传    checkFileIsUpload: function (fileSuf, suffixs) {        var status = false;        this.forEach(suffixs, function (i, n) {            if (fileSuf.toLowerCase() === n.toLowerCase()) {                status = true;                return false;            }        });        return status;    },    //选择上传文件    chooseFile: function () {        if (this.settings.perviewImageElementId) {            $("#" + this.settings.perviewImageElementId).empty();        }        var uploadfile = this.getUploadInput();        $(uploadfile).val("").click();    }};//图片预览操作var perviewImage = {    timers: [],    //获取预览元素    getElementObject: function (elem) {        if (elem.nodeType && elem.nodeType === 1) {            return elem;        } else {            return document.getElementById(elem);        }    },    //开始图片预览    beginPerview: function (/*文件上传控件实例*/file, /*需要显示的元素id或元素实例*/perviewElemId, /*上传页面所在的document对象*/ dcmt, /*上传辅助类实例*/upload) {        this.imageOperation(file, perviewElemId, dcmt, upload);    },    //图片预览操作    imageOperation: function (/*文件上传控件实例*/file, /*需要显示的元素id或元素实例*/perviewElemId, /*上传页面所在的document对象*/ dcmt, /*上传辅助类实例*/upload) {        for (var t = 0; t < this.timers.length; t++) {            window.clearInterval(this.timers[t]);        }        this.timers.length = 0;        var tmpParams = {            onChange: function (c) {                upload.setImageCropperObj(c);            },            onSelect: function (c) {                upload.setImageCropperObj(c);            }        };        var sWidth = 50, sHeight = 50;        if (upload.settings.cropperParam.minSize) {            var size = upload.settings.cropperParam.minSize;            sWidth = size[0] > sWidth ? size[0] : sWidth;            sHeight = size[1] > sHeight ? size[1] : sHeight;        }        var params = $.extend({}, tmpParams, upload.settings.cropperParam || {});        var preview_div = this.getElementObject(perviewElemId);        var MAXWIDTH = preview_div.clientWidth;        var MAXHEIGHT = preview_div.clientHeight;        upload.setMaxWidthAndHeight(MAXWIDTH, MAXHEIGHT);        if (file.files && file.files[0]) { //此处为Firefox,Chrome以及IE10的操作            preview_div.innerHTML = "";            var img = document.createElement("img");            preview_div.appendChild(img);            img.style.visibility = "hidden";            img.onload = function () {                var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);                img.style.width = rect.width + 'px';                img.style.height = rect.height + 'px';                img.style.visibility = "visible";                var offsetWidth = (rect.width / 2) - (sWidth / 2);                var offsetHeight = (rect.height / 2) - (sHeight / 2);                var obj = {                    x: offsetWidth,                    y: offsetHeight,                    x2: offsetWidth + sWidth,                    y2: offsetHeight + sHeight,                    w: sWidth,                    h: sHeight                };                $(img).Jcrop(params, function () {                    upload.jcropApi = this;                    this.animateTo([obj.x, obj.y, obj.x2, obj.y2]);                    upload.setImageCropperObj(obj);                });            };            var reader = new FileReader();            reader.onload = function (evt) {                img.src = evt.target.result;            };            reader.readAsDataURL(file.files[0]);        } else { //此处为IE6,7,8,9的操作            file.select();            var src = dcmt.selection.createRange().text;            var div_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + src + "')";            var img_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image',src='" + src + "')";            preview_div.innerHTML = "";            var img = document.createElement("div");            preview_div.appendChild(img);            img.style.filter = img_sFilter;            img.style.visibility = "hidden";            img.style.width = "100%";            img.style.height = "100%";            function setImageDisplay() {                var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);                preview_div.innerHTML = "";                var div = document.createElement("div");                div.style.width = rect.width + 'px';                div.style.height = rect.height + 'px';                div.style.filter = div_sFilter;                var offsetWidth = (rect.width / 2) - (sWidth / 2);                var offsetHeight = (rect.height / 2) - (sHeight / 2);                var obj = {                    x: offsetWidth,                    y: offsetHeight,                    x2: offsetWidth + sWidth,                    y2: offsetHeight + sHeight,                    w: sWidth,                    h: sHeight                };                preview_div.appendChild(div);                $(div).Jcrop(params, function () {                    upload.jcropApi = this;                    this.animateTo([obj.x, obj.y, obj.x2, obj.y2]);                    upload.setImageCropperObj(obj);                });            }            //图片加载计数            var tally = 0;            var timer = window.setInterval(function () {                if (img.offsetHeight != MAXHEIGHT) {                    window.clearInterval(timer);                    setImageDisplay();                } else {                    tally++;                }                //如果超过两秒钟图片还不能加载,就停止当前的轮询                if (tally > 20) {                    window.clearInterval(timer);                    setImageDisplay();                }            }, 100);            this.timers.push(timer);        }    },    //按比例缩放图片    clacImgZoomParam: function (maxWidth, maxHeight, width, height) {        var param = { width: width, height: height };        if (width > maxWidth || height > maxHeight) {            var rateWidth = width / maxWidth;            var rateHeight = height / maxHeight;            if (rateWidth > rateHeight) {                param.width = maxWidth;                param.height = Math.round(height / rateWidth);            } else {                param.width = Math.round(width / rateHeight);                param.height = maxHeight;            }        }        param.left = Math.round((maxWidth - param.width) / 2);        param.top = Math.round((maxHeight - param.height) / 2);        return param;    },    //创建图片预览元素    createPreviewElement: function (/*关闭图片名称*/name, /*上传时的文件名*/file, /*预览时的样式*/style) {        var img = document.createElement("div");        img.title = file;        img.style.overflow = "hidden";        for (var s in style) {            img.style[s] = style[s];        }        var text = document.createElement("div");        text.style.width = style.width;        text.style.overflow = "hidden";        text.style.textOverflow = "ellipsis";        text.style.whiteSpace = "nowrap";        text.innerHTML = file;        var main = document.createElement("div");        main.appendChild(img);        main.appendChild(text);        return main;    },    //获取上传文件大小    getFileSize: function (/*上传控件dom对象*/file, /*上传控件所在的document对象*/dcmt) {        var fileSize;        if (file.files && file.files[0]) {            fileSize = file.files[0].size;        } else {            file.select();            var src = dcmt.selection.createRange().text;            try {                var fso = new ActiveXObject("Scripting.FileSystemObject");                var fileObj = fso.getFile(src);                fileSize = fileObj.size;            } catch (e) {                return "error";            }        }        fileSize = ((fileSize / 1024) + "").split(".")[0];        return fileSize;    }};
这里也给出Jcrop插件的下载地址,有需要的可以去下载

http://code.ciaoca.com/jquery/jcrop/

当然服务端我们如何处理喃?这里我使用了asp.net的webform作为示例(同样你也可以使用其他形式的服务端,像php  java  mvc......),代码如下

    public partial class WebForm1 : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            var x = Request.Params["x1"];     //水平偏移量            var y = Request.Params["y1"];     //垂直偏移量            var x2 = Request.Params["x2"];    //水平偏移量 + 截取宽度            var y2 = Request.Params["y2"];    //垂直偏移量 + 截取高度            var w = Request.Params["w"];      //截取宽度            var h = Request.Params["h"];      //截取高度            var maxW = Request.Params["maxW"];//客户端截取时,图片的最大宽度            var maxH = Request.Params["maxH"];//客户端截取时,图片的最大高度            HttpFileCollection files = Request.Files;            var fileName = string.Empty;            for (var i = 0; i < files.Count; i++)            {                //首先将图片缩放到与客户端截取时的大小一致                using (var bitmap = GenerateThumbnail(int.Parse(maxW), int.Parse(maxH), files[i].InputStream))                {                    fileName = DateTime.Now.Ticks + ".jpg";                    var newFileName = Server.MapPath("/uploadImg") + "/" + fileName;                    //开始截取                    ImageCropper(bitmap, int.Parse(w), int.Parse(h), int.Parse(x), int.Parse(y), newFileName,                                 System.Drawing.Imaging.ImageFormat.Jpeg);                }            }            //上传成功,这里只输出文件名,作为示例这样就够了            Response.Write("/uploadImg/" + fileName);            //上传失败            // Response.Write("error");            Response.Flush();            Response.End();        }        /// <summary>        /// 生成指定大小的图片        /// </summary>        /// <param name="maxWidth">生成图片的最大宽度</param>        /// <param name="maxHeight">生成图片的最大高度</param>        /// <param name="imgFileStream">图片文件流对象</param>        private System.Drawing.Bitmap GenerateThumbnail(int maxWidth, int maxHeight, System.IO.Stream imgFileStream)        {            using (var img = System.Drawing.Image.FromStream(imgFileStream))            {                var sourceWidth = img.Width;                var sourceHeight = img.Height;                var thumbWidth = sourceWidth; //要生成的图片的宽度                var thumbHeight = sourceHeight; //要生成图片的的高度                //计算生成图片的高度和宽度                if (sourceWidth > maxWidth || sourceHeight > maxHeight)                {                    var rateWidth = (double) sourceWidth/maxWidth;                    var rateHeight = (double) sourceHeight/maxHeight;                    if (rateWidth > rateHeight)                    {                        thumbWidth = maxWidth;                        thumbHeight = (int) Math.Round(sourceHeight/rateWidth);                    }                    else                    {                        thumbWidth = (int) Math.Round(sourceWidth/rateHeight);                        thumbHeight = maxHeight;                    }                }                var bmp = new System.Drawing.Bitmap(thumbWidth, thumbHeight);                //从Bitmap创建一个System.Drawing.Graphics对象,用来绘制高质量的缩小图。                using (var gr = System.Drawing.Graphics.FromImage(bmp))                {                    //设置 System.Drawing.Graphics对象的SmoothingMode属性为HighQuality                    gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;                    //下面这个也设成高质量                    gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;                    //下面这个设成High                    gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;                    //把原始图像绘制成上面所设置宽高的缩小图                    var rectDestination = new System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight);                    gr.DrawImage(img, rectDestination, 0, 0, sourceWidth, sourceHeight,                                 System.Drawing.GraphicsUnit.Pixel);                    return bmp;                }            }        }        /// <summary>        /// 截取图片中的一部分        /// </summary>        /// <param name="img">待截取的图片</param>        /// <param name="cropperWidth">截取图片的宽</param>        /// <param name="cropperHeight">截取图片的高</param>        /// <param name="offsetX">水平偏移量</param>        /// <param name="offsetY">垂直偏移量</param>        /// <param name="savePath">截取后的图片保存位置</param>        /// <param name="imgFormat">截取后的图片保存格式</param>        private void ImageCropper(System.Drawing.Image img, int cropperWidth, int cropperHeight, int offsetX,                                  int offsetY, string savePath,                                 System.Drawing.Imaging.ImageFormat imgFormat)        {            using (var bmp = new System.Drawing.Bitmap(cropperWidth, cropperHeight))            {                //从Bitmap创建一个System.Drawing.Graphics对象,用来绘制高质量的缩小图。                using (var gr = System.Drawing.Graphics.FromImage(bmp))                {                    //设置 System.Drawing.Graphics对象的SmoothingMode属性为HighQuality                    gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;                    //下面这个也设成高质量                    gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;                    //下面这个设成High                    gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;                    //把原始图像绘制成上面所设置宽高的截取图                    var rectDestination = new System.Drawing.Rectangle(offsetX, offsetY, cropperWidth, cropperHeight);                    gr.DrawImage(img, 0, 0, rectDestination,                                 System.Drawing.GraphicsUnit.Pixel);                    //保存截取的图片                    bmp.Save(savePath, imgFormat);                }            }        }    }
服务端其实也很简单,我想应该都看得明白吧!关键是思路,我们首先将图片缩放到和客户端截取时相同的大小,然后再在这个缩放的图上进行截取 就这么简单,这样就能保证截取到相同位置的图片,好了 最后祝有需要的童鞋项目顺利,心想事成




5 0