.Net平台移动端实现图像上传、压缩及预览功能详解
最近再给公司做移动端开发图像上传裁剪压缩以及预览的功能,给大家分享一点心得,首先给大家看一下最终实现效果:
首先是前端把图片转化成base64格式然后通过ajax异步发送到服务器
html部分
<div style="background-color:#fff;margin-top:-5px;padding:0px 8px;">
<img onclick="DeleteImage(this)" id="ImgShow1" class="ImgPreHidden" src="" alt="" />
<img onclick="DeleteImage(this)" id="ImgShow2" class="ImgPreHidden" src="" alt="" />
<img onclick="DeleteImage(this)" id="ImgShow3" class="ImgPreHidden" src="" alt="" />
<img onclick="DeleteImage(this)" id="ImgShow4" class="ImgPreHidden" src="" alt="" />
<image id="ImgUploadButtom" onclick="$('#ImgUpload').click()" style="width:80px;height:80px;margin-bottom:2px;" src="../../../../Content/image/camera.png" />
<input type="file" id="ImgUpload" style="display:none;" />
</div>
javascript部分
$("#ImgUpload").on("change", headPortraitListener);
/*头像上传监听*/
function headPortraitListener(e) {
var ImgShowI = 0;
for (var i = 1; i <= 4; i++) {
if ($("#ImgShow" + i).attr("src") == "") {
ImgShowI = i;
break;
}
}
var img = document.getElementById("ImgShow" + i);
if (window.FileReader) {
var file = e.target.files[0];
var reader = new FileReader();
if (file && file.type.match('image.*')) {
reader.readAsDataURL(file);
} else {
img.setAttribute('class', 'ImgPreHidden');
img.setAttribute('src', '');
}
reader.onloadend = function (e) {
UploadImage(img, reader.result);
}
}
}
/*删除图片*/
function DeleteImage(e) {
$(e).attr('class', 'ImgPreHidden');
$(e).attr('src', '');
$("#ImgUploadButtom").show();
}
/*上传图片*/
function UploadImage(img,base64Image) {
var postData = {};
postData["Bill_Id"] = $("#ID").val();
postData["Base64Image"] = base64Image;
AjaxJson("/UploadImage", "json=" + JSON.stringify(postData), function (result) {
if (result.status == "1") {
img.setAttribute('src', base64Image);
img.setAttribute('class', 'ImgPreShow');
IsImage();
} else {
_layer.msg(result.message);
}
})
}
function IsImage() {
var ImgShowI = 0;
for (var i = 1; i <= 4; i++) {
if ($("#ImgShow" + i).attr("src") == "") {
ImgShowI = i;
break;
}
}
if (ImgShowI == 0) {
$("#ImgUploadButtom").hide();
return;
}
}
C#后端部分
public ActionResult UploadImage(string json)
{
SH.Entity.CommonModule.CommonResult<Hashtable> result = new SH.Entity.CommonModule.CommonResult<Hashtable>();
try
{
Base_Image entity = json.JsonToEntity<Base_Image>();
var Image = SH.Utilities.Base.Media.ImageExt.Compression(entity.Base64Image, 1000);
entity.Id = Guid.NewGuid().ToString();
using (MiniPoco.Database db = new MiniPoco.Database())
{
var data_type = entity.Base64Image.Split(',');
string Ext = data_type[0].Split('/')[1].Split(';')[0];
string _Url = "\\WeChat\\" + DateTime.Now.ToString("yyyy-MM");
entity.CreateDate = DateTime.Now;
string fileName = entity.Id + "." + Ext;
entity.Status = 0;
entity.Url = _Url + "\\" + fileName;
string ImageFilePath = "\\\\网盘地址" + _Url;
if (System.IO.Directory.Exists(ImageFilePath) == false)//如果不存在就创建文件夹
{
System.IO.Directory.CreateDirectory(ImageFilePath);
}
string ImagePath = ImageFilePath + "\\" + fileName;//定义图片名称
Image.Save(ImagePath); //保存图片到服务器,然后获取路径
db.Insert<Base_Image>(entity);
db.Save();
result.status = "1";
result.message = entity.Id;
return Content(result.ToJson());
}
}
catch (Exception ex)
{
result.status = "0";
result.message = ex.Message;
return Content(result.ToJson());
}
}
使用PhotoSwipe实现图片的预览功能
引入必要的css和js
<!-- Core CSS file -->
<link href="../../../../Content/js/plugins/PhotoSwipe/photoswipe.css" rel="stylesheet" type="text/css" />
<!-- Skin CSS file (styling of UI - buttons, caption, etc.)
In the folder of skin CSS file there are also:
- .png and .svg icons sprite,
- preloader.gif (for browsers that do not support CSS animations) -->
<link href="../../../../Content/js/plugins/PhotoSwipe/default-skin/default-skin.css" rel="stylesheet" type="text/css" />
<!-- Core JS file -->
<script src="../../../../Content/js/plugins/PhotoSwipe/photoswipe.min.js" type="text/javascript"></script>
<!-- UI JS file -->
<script src="../../../../Content/js/plugins/PhotoSwipe/photoswipe-ui-default.min.js" type="text/javascript"></script>
html部分
<div id="layer-photos-demo" class="line-div" style="margin-top:5px;">
<img onclick="openPhotoSwipe(1)" id="ImgShow1" class="ImgPreHidden" layer-src="" src="" alt="" />
<img onclick="openPhotoSwipe(2)" id="ImgShow2" class="ImgPreHidden" layer-src="" src="" alt="" />
<img onclick="openPhotoSwipe(3)" id="ImgShow3" class="ImgPreHidden" layer-src="" src="" alt="" />
<img onclick="openPhotoSwipe(4)" id="ImgShow4" class="ImgPreHidden" layer-src="" src="" alt="" />
</div>
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element, as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides. PhotoSwipe keeps only 3 slides in DOM to save memory. -->
<div class="pswp__container">
<!-- don't modify these 3 pswp__item elements, data is added later on -->
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--active pswp__ui--fit">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close(Esc)"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
javascript部分
var PhotoSwipe_items = [
{
src: '/GetImage?Id=95b5e811-3796-4841-9960-d6d03815baea.jpeg',
w: 1000,
h: 750
},
{
src: '/GetImage?Id=bb128132-0e9d-4bf7-b68b-aedb89d8d8b2.jpeg',
w: 1000,
h: 750
}];
var openPhotoSwipe = function (i) {
var pswpElement = document.querySelectorAll('.pswp')[0];
// define options (if needed)
var options = {
// history & focus options are disabled on CodePen
history: false,
focus: false,
index:i-1,
showAnimationDuration: 0,
hideAnimationDuration: 0
};
var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, PhotoSwipe_items, options);
gallery.init();
};
给大家看一下图像压缩前和压缩后的对比
压缩前
压缩后
最后补充一下图片压缩功能的代码
public static Image Compression(string Base64String, int width)
{
long quality = 90;//壓縮質量0-100之間 數值越大質量越高
string ImageType = Base64String.Split(',')[0];
string temp = Base64String.Split(',')[1];
temp = temp.Replace(" ", "+");
int mod4 = temp.Length % 4;
if (mod4 > 0)
{
temp += new string('=', 4 - mod4);
}
byte[] btsdata = Convert.FromBase64String(temp);
MemoryStream ms = new MemoryStream(btsdata);
Image img = Image.FromStream(ms);
int height = (int)img.Height * width / img.Width;
Bitmap _bitmap = new Bitmap(width, height);
Graphics _graphics = Graphics.FromImage(_bitmap);
//设置图片质量
_graphics.InterpolationMode = InterpolationMode.Low;
_graphics.SmoothingMode = SmoothingMode.None;
//绘制图片
_graphics.Clear(Color.Transparent);
_graphics.DrawImage(img, 0, 0, _bitmap.Width, _bitmap.Height);
//压缩
ImageCodecInfo CodecInfo = GetEncoder(img.RawFormat);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
myEncoderParameters.Param[0] = myEncoderParameter;
//保存
using (MemoryStream memorystream = new MemoryStream())
{
_bitmap.Save(memorystream, CodecInfo, myEncoderParameters);
myEncoderParameters.Dispose();
myEncoderParameter.Dispose();
_graphics.Dispose();
img.Dispose();
_bitmap.Dispose();
return BytesToImage(memorystream.ToArray());
}
}
private static Image BytesToImage(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer);
Image image = System.Drawing.Image.FromStream(ms);
return image;
}
private static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{ return codec; }
}
return null;
}