需求:
需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况)
文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用的 1.1的版本
效果:
服务器目录展示:
里面对应目录层级的图片
前端提交POST请求案例:
function DownAllFile(filename, imgUrl, down) {
var urlStr = "";
???????????//url字符串 (示例数据) (注意!: 使用 ‘逗号‘ 分隔文件名和 url 地址,使用 ‘$‘ 分隔 每个文件.)
???????????if (filename != ‘‘ && imgUrl != ‘‘)
???????????????urlStr = filename + "," + imgUrl;
???????????//form提交
???????????var form = $(‘<form>‘);
???????????form.attr(‘style‘, ‘display:none‘);
???????????form.attr(‘target‘, ‘‘);
???????????form.attr(‘method‘, ‘post‘);
???????????form.attr(‘action‘, ‘/PayStripe.ashx?method=DownLoadImage‘); ?//这里写对应的方法地址
???????????var name1 = $(‘<input>‘);
???????????name1.attr(‘type‘, ‘text‘);
???????????name1.attr(‘name‘, ‘urlStr‘);
???????????name1.attr(‘value‘, urlStr); //文件url
???????????if (down == "P") {
???????????????var vals = "";
???????????????$.each($(‘input:checkbox:checked‘), function () {
???????????????????vals += $(this).val() + ",";
???????????????});
???????????????var checkbox1 = $(‘<input>‘);
???????????????checkbox1.attr(‘type‘, ‘text‘);
???????????????checkbox1.attr(‘name‘, ‘coid‘);
???????????????checkbox1.attr(‘value‘, vals); //文件url
???????????????form.append(checkbox1);
???????????}
???????????$(‘body‘).append(form);
???????????form.append(name1);
???????????form.submit();
???????????form.remove();
???????}
后端实现代码:
//得到文件信息(名字,地址) (去掉最后一个 ‘$‘ , 并用 ‘$‘ 分隔字符串. 取到每个文件的文件名和路径 )
???????????string[] urlArray = model.urlStr.TrimEnd(‘$‘).Split(‘$‘);
???????????//存 文件名 和 数据流
???????????Dictionary<string, Stream> dc = new Dictionary<string, Stream>();
???????????//取出字符串中信息 (文件名和地址)
???????????for (int i = 0; i < urlArray.Length; i++)
???????????{
???????????????WebClient myWebClient = new WebClient();
???????????????//使用 ‘,‘ 分隔 文件名和路径 [0]位置是文件名, [1] 位置是路径
???????????????string[] urlSp = urlArray[i].Split(‘,‘);
???????????????//调用WebClient 的 DownLoadData 方法 下载文件
???????????????byte[] data = myWebClient.DownloadData(urlSp[1].Replace("_PB.jpg", "_B.jpg"));
???????????????Stream stream = new MemoryStream(data);//byte[] 转换成 流
???????????????//放入 文件名 和 stream
???????????????dc.Add(urlSp[0] + ".jpg" + "," + urlSp[2], stream);//这里指定为 .doc格式 (自己可以随时改)
???????????????if (urlArray.Length == 1)
???????????????{
???????????????????Image img = Image.FromStream(stream);
???????????????????MemoryStream ms = new MemoryStream();
???????????????????img.Save(ms, ImageFormat.Jpeg);
???????????????????img.Dispose();
???????????????????context.Response.ClearContent();
???????????????????context.Response.ContentType = "application/octet-stream";
???????????????????context.Response.AppendHeader("Content-Disposition", "attachment;filename=" + urlSp[0] + ".jpeg");//文件名和格式(格式可以自己定)
???????????????????context.Response.ContentType = "image/jpeg";
???????????????????context.Response.BinaryWrite(ms.ToArray());
???????????????????return;
???????????????}
???????????}
???????????//调用压缩方法 进行压缩 (接收byte[] 数据)
???????????byte[] fileBytes = ConvertZipStream(dc);
???????????context.Response.ContentType = "application/octet-stream";
???????????context.Response.AppendHeader("Content-Disposition", "attachment;filename=SoonnetImage.rar");//文件名和格式(格式可以自己定)
???????????context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());//文件大小
???????????context.Response.BinaryWrite(fileBytes); //放入byte[]
???????????context.Response.End();
???????????context.Response.Close();
/// <summary>
???????/// ZipStream 压缩
???????/// </summary>
???????/// <param name="streams">Dictionary(string, Stream) 文件名和Stream</param>
???????/// <returns></returns>
???????public static byte[] ConvertZipStream(Dictionary<string, Stream> streams)
???????{
???????????byte[] buffer = new byte[6500];
???????????MemoryStream returnStream = new MemoryStream();
???????????var zipMs = new MemoryStream();
???????????using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(zipMs))
???????????{
???????????????zipStream.SetLevel(9);//设置 压缩等级 (9级 500KB 压缩成了96KB)
???????????????foreach (var kv in streams)
???????????????{
???????????????????string[] fileName = kv.Key.Split(‘,‘);
???????????????????using (var streamInput = kv.Value)
???????????????????{
???????????????????????zipStream.PutNextEntry(new ICSharpCode.SharpZipLib.Zip.ZipEntry(fileName[1] + "/" + fileName[0])); //主要是这里可以分文件夹自动压缩
???????????????????????while (true)
???????????????????????{
???????????????????????????var readCount = streamInput.Read(buffer, 0, buffer.Length);
???????????????????????????if (readCount > 0)
???????????????????????????{
???????????????????????????????zipStream.Write(buffer, 0, readCount);
???????????????????????????}
???????????????????????????else
???????????????????????????{
???????????????????????????????break;
???????????????????????????}
???????????????????????}
???????????????????????zipStream.Flush();
???????????????????}
???????????????}
???????????????zipStream.Finish();
???????????????zipMs.Position = 0;
???????????????zipMs.CopyTo(returnStream, 5600);
???????????}
???????????returnStream.Position = 0;
???????????//Stream转Byte[]
???????????byte[] returnBytes = new byte[returnStream.Length];
???????????returnStream.Read(returnBytes, 0, returnBytes.Length);
???????????returnStream.Seek(0, SeekOrigin.Begin);
???????????return returnBytes;
???????}
注:
文章中代码有牵扯到 1 长图片点击直接下载的功能,可以删除部分逻辑实现,不同文件夹压缩图片功能。
该压缩并非会压缩图片本身,解压后,图片的大小跟实际大小一致。
.NET压缩图片保存
原文地址:https://www.cnblogs.com/Mrly/p/10219088.html