.Net平台移动端实现图像上传、压缩及预览功能详解

8 篇文章 0 订阅
7 篇文章 0 订阅

最近再给公司做移动端开发图像上传裁剪压缩以及预览的功能,给大家分享一点心得,首先给大家看一下最终实现效果:

首先是前端把图片转化成base64格式然后通过ajax异步发送到服务器

html部分

<div style="background-color:#fff;margin-top:-5px;padding:0px 8px;">
 <img onclick="DeleteImage(this)" id="ImgShow0" class="ImgPreHidden" src="" alt="" />
 <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部分

使用canvas对象对图片进行压缩,使用exif.js解决部分手机拍照之后图片旋转问题

$("#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;
		}
	}
	if (ImgShowI == 0) {
		_layer.msg("最多只能上传4张图片");
		return;
	}

	var img = document.getElementById("ImgShow" + i);
	var img0 = document.getElementById("ImgShow0");
	if (window.FileReader) {
		var file = e.target.files[0];
		 EXIF.getData(file, function () {
			Orientation = EXIF.getTag(this, 'Orientation');
		});
		var reader = new FileReader();
		if (file && file.type.match('image.*')) {
			reader.readAsDataURL(file);
		} else {
			img.setAttribute('class', 'ImgShow ImgPreHidden');
			img.setAttribute('src', '');
		}
		reader.onloadend = function (e) {
			img0.setAttribute('src', reader.result);
		}
		img0.onload = function () {
			var imgWidth = this.width,
							imgHeight = this.height;
			console.log(this);
			if (imgWidth > imgHeight && imgWidth > 1000) {
				imgWidth = 1000;
				imgHeight = Math.ceil(1000 * this.height / this.width);
			} else if (imgWidth < imgHeight && imgHeight > 1334) {
				imgWidth = Math.ceil(1334 * this.width / this.height);
				imgHeight = 1334;
			}

			var canvas = document.createElement("canvas"),
						ctx = canvas.getContext('2d');
			canvas.width = imgWidth;
			canvas.height = imgHeight;
			if (Orientation && Orientation != 1) {
				switch (Orientation) {
					case 6:
						canvas.width = imgHeight;
						canvas.height = imgWidth;
						ctx.rotate(Math.PI / 2);
						ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight);
						break;
					case 3:
						ctx.rotate(Math.PI);
						ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight);
						break;
					case 8:
						canvas.width = imgHeight;
						canvas.height = imgWidth;
						ctx.rotate(3 * Math.PI / 2);
						ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
						break;
				}
			} else {
				ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
			}

			UploadImage(img, canvas.toDataURL("image/jpeg", 0.8));
		}
	}
}
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("/ExtensionApp/ComplaintMailbox/UploadImage", "json=" + JSON.stringify(postData), function (result) {
		if (result.status == "1") {
			img.setAttribute('src', base64Image);
			img.setAttribute('class', 'ImgShow 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;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖狗-小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值