C#-图片的上传、保存和读取

Vue实现图片上传、保存和读取

前段时间收到一个开发任务,在原有功能基础上增加一个上传图片的功能,对于一个入职半年没这方面经验的新人来说有一定难度。在实现过程中,很多细节问题都是通过百度解决的,下面分享我的解决方法(截取部分代码),写的不好或者不对的地方,欢迎各位朋友不吝赐教。 

主体思路:

  • 先把图片上传到一个临时文件夹中,上传成功后可以点击预览,保存时,以字节数组形式读取临时文件夹中的图片,读取完成立即清除临时文件夹中的图片,将包含图片信息的字节数组作为一个变量存入数据库中
  • 读取图片同理,将从数据库中读取到的字节数组转为Base64字符串,传到JS中作为图片的src,即可显示图片。

1、前端使用的是vue-element,代码如下:

<el-form-item label="上传模板图片:" v-if="carryForm.childTemplateType!='网点直连'"   prop="TemplateFileName">
    <el-upload class="upload-demo" style="width:600px;"
               multiple="false"
               drag
               ref="upload"
               action="/UpLoadFile/TemplateBasicsUpLoadPic"
               :before-upload="checkUploadPic"
               :on-change="handleChangePic"
               :on-preview="handlePictureCardPreview"
               :on-remove="handleRemove"
               :on-success="HandleSuccess">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text" v-html="mainInfo.PageTitle[0]"></div>
    </el-upload>
    <el-dialog :visible.sync="innerVisible" :width="width" append-to-body>
        <el-form :model="templatePicForm">
            <el-image style="width:auto; height: auto"
                      :src="dialogImageUrl">
            </el-image>
        </el-form>
    
    </el-dialog>
    <span id="TipHint" style="position:absolute;top:230px;left:2px;color:red;" hidden>点击可预览图片</span>
</el-form-item>

关于element的上传组件的使用,推荐一个网站,非常方便还有实例:Element-Upload,建议收藏!
Action方法TemplateBasicsUpLoadPic放在外部控制器里面,上传的图片保存到临时文件夹TemplFiles中,上传成功返回图片路径:
在这里插入图片描述

public string TemplateBasicsUpLoadPic()
        {
            try
            {
                var fs = HttpContext.Request.Files;
                if (fs == null || fs.Count == 0) return "";

                var file = fs[0];
                var savePath = $"{AppDomain.CurrentDomain.BaseDirectory}TemplFiles\\{file.FileName}";
                var dirName = Path.GetDirectoryName(savePath);
                if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName);
                file.SaveAs(savePath);
                return savePath;
            }
            catch
            {
                return "";
            }
        }

2、JS代码,由于数据库中存储图片的字段设定的是blob类型,最大只能存储65KB的内容,但是我在自己调试的时候发现64到65KB大小的图片也是无法保存的,所以在上传时限制在64KB以内

  • tinyblob:仅255个字符
  • blob:最大限制到65K字节
  • mediumblob:限制到16M字节
  • longblob:可达4GB
data:{
......
	dialogImageUrl: '',
	width: '',
	innerVisible: false,//图片预览Dialog初始不显示
	templatePicForm: {
	},
......
},
methods:{
......
	checkUploadPic(file) {
		let _this = this;
		if (!(file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpg' || file.type === 'image/jpeg')) {
			$.msg.warning("上传文件不是图片,请重新选择!");
			return false;
		}
		let size = file.size / 1024;
		if (size > 64) {
			$.msg.warning("图片必须小于64KB!");
			return false;
		}
		_this.carryForm.TemplateFileName = file.name;
	},
	handleChangePic(file, fileList) {
		if (fileList.length > 1) {
			$.msg.warning("仅限上传一张图片,请先清除,再上传!");
			this.fileList = fileList.splice(-1);
		}
	},
	//on-preview	点击文件列表中已上传的文件时的钩子(预览图片弹窗)
	handlePictureCardPreview(file) {
		let _this = this;
	
		this.width = 0 + 'px';
		var windowURL = window.URL || window.webkitURL;
		var dataURL = windowURL.createObjectURL(file.raw);
		this.dialogImageUrl = dataURL;
		var img = new Image();
		img.src = dataURL;
		img.onload = function () {
			if (img.width > window.innerWidth) _this.width = window.innerWidth - 40 + 'px';
			else _this.width = img.width + 50 + 'px';
		};
		this.innerVisible = true;//显示图片预览Dialog
	},
	
	HandleSuccess(response, file, filelist) {
		let _this = this;
		if (response != "") {
			_this.carryForm.ImagePath = response;
			this.$message({ showClose: true, message: '上传成功!', type: 'success' });
			this.$refs.carryFormRef.valid = true;
			$("#TipHint").show();
			setTimeout(function () {
				$("#TipHint").hide();
			}, 2000);
		}
		else
			$.msg.error("上传失败,请检查!");
	},
	handleRemove(file) {//对上传成功的图片进行删除
		let _this = this;
		$.post('/Print/TemplatebasicsOperate/DeleteFile?Url=' + file.response).then(function () {
	
		});
	},
......
}

删除临时文件夹中上传成功的图片:

public void DeleteFile(String Url)
{
    if (Url != "undefined")
    {
        try
        {
            File.ReadAllBytes(Url);
            var dirName = Path.GetDirectoryName(Url);
            if (Directory.Exists(dirName)) File.Delete(Url);
        }
        catch (Exception ex) { }
    }
}

3、点击保存后,JS提交数据到Controller后,转逻辑层进行处理,读取临时文件夹中的图片,保存为字节数组,将该数组存入数据库:

......
try
{
    byte[] byData = null;
    byData = File.ReadAllBytes(model.ImagePath);//读取图片保存到字节数组
    string extensionName = System.IO.Path.GetExtension(model.ImagePath);//获取文件后缀名
    var dirName = Path.GetDirectoryName(model.ImagePath);
    if (Directory.Exists(dirName))//读取完删除临时文件
    {
        DirectoryInfo dir = new DirectoryInfo(dirName);
        FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();
        foreach (FileSystemInfo i in fileinfo)
        {
            File.Delete(i.FullName);
        }
    }

    if (UpFileIsLegal(model.ImagePath))
    {
        model.TemplatePic = byData;//把字节数组赋给存储对象
    }
}
catch (Exception ex)
{
    Plugins.LogManager.Error(ex);
}
......

4、从数据库中读取图片:

/// <summary>
/// 图片预览
/// </summary>
/// <param name="TemplateNo"></param>
/// <returns>Base64字符流</returns>
public String TemplatePicview(int TemplateNo)
{
    string sql = "SELECT TemplatePic FROM tt_print_templatebasics WHERE TemplateNo=@TemplateNo ";
    using (var connection = DapperConnection.GetConnectionDatabase("ERP_Master"))
    {
        byte[] _byte = null;
        _byte = connection.Query<byte[]>(sql, new { TemplateNo }).FirstOrDefault();//用byte数据接收二进制数据
        if (_byte != null)
        {
            string srcBase64Str = "data:image/png;base64," + Convert.ToBase64String(_byte);
            return srcBase64Str;//srcBase64Str返到JS后,可直接作为图片的src
        }
        return "false";

    }
}
<!--图片弹窗-->
    <el-dialog style="font-weight: bold;margin-top:-35px !important;" title="图片预览" :visible.sync="dialogPicFormVisible" v-if="dialogPicFormVisible" :close-on-click-modal="false" :width="width" @@close="dialogClose">
        <el-form :model="templatePicForm">
            <el-image style="width:auto; height: auto"
                      :src="templatePicFormsrc">
            </el-image>
        </el-form>
        <div slot="footer" class="dialog-footer" style="text-align:center;">
            <el-button v-on:click="dialogPicFormVisible = false">关闭</el-button>
        </div>
    </el-dialog>
data: {
......
    dialogPicFormVisible: false,
    width: '',
......
},
......
//预览
PreviewTemplateInfo: function (row) {
    var templateID = "1" + row.TemplateNo;

        let _this = this;
        $.get('/print/TemplatebasicsInfo/TemplatePicview?TemplateNo=' + row.TemplateNo).then(function (result) {
            if (result != "false") {
                _this.templatePicFormsrc = result;
                var img = new Image();
                img.src = result;
                img.onload = function () {//此方法作用是限制图片大小不会超出屏幕范围
                    if (img.width > window.innerWidth) _this.width = window.innerWidth - 40 + 'px';
                    else _this.width = img.width + 50 + 'px';
                };
                _this.dialogPicFormVisible = true;
            }
            else {
                $.msg.warning("预览失败!未查询到图片");
            }
        });   
},
......

5、效果图:
点击选择图片上传:
上传图片

图片上传成功,点击×可以删除图片:
图片上传成功

点击图片名预览:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

qq_41860033

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值