当前位置: 首页 > news >正文

将图片存为二进制流到数据库并展示到前端的实现

使用图片直接存储到数据库中可能会出现以下问题:

1.图片的存储太多了占用数据库的存储空间

2.图片占用内存较大在传输和渲染的情况下会影响应用性能

3.一般情况下是将图片上传云服务器然后数据库存地址,这里讲解的情况只适合图片较少的情景

这里使用的是微信小程序和webapi,sqlserver(理论上思路是一样的)

在微信小程序中我们先需要一个image容器存图片:

			<!-- 头像上传 --><view class="form-avatar-section"><view class="avatar-uploader {{avatar ? 'has-avatar' : ''}}" bindtap="chooseAvatar"><image class="avatar-preview" src="{{avatar || '/icons/photo-camera.png'}}" mode="aspectFill" /><view wx:if="{{!avatar}}" class="uploader-mask"><image src="/icons/add-photo.png" class="upload-icon" /><text>点击上传照片</text></view></view></view>

头像的样式你们也可以参考:

 

/* 头像上传区 */
.form-avatar-section {padding: 48rpx 0;background: #f8fafc;display: flex;justify-content: center;
}.avatar-uploader {width: 200rpx;height: 200rpx;border-radius: 50%;position: relative;border: 4rpx solid #e2e8f0;overflow: hidden;
}.avatar-preview {width: 100%;height: 100%;
}.uploader-mask {position: absolute;width: 100%;height: 100%;background: rgba(241, 245, 249, 0.8);display: flex;flex-direction: column;align-items: center;justify-content: center;
}.upload-icon {width: 56rpx;height: 56rpx;margin-bottom: 16rpx;opacity: 0.6;
}

以下是在js中的实现,因为我使用表单提交的,所以其中多了个formData, formData中的avatar是存储base64String类型数据,单独的avatar是存储的图片缓存地址

 

实现获取图片的方法:

 // 头像上传chooseAvatar() {var that = this;wx.chooseMedia({  //这个方法微信开发文档有详细讲解count: 1,mediaType: ['image'], //限制只能选中图片sizeType: ['compressed'],success: res => {const tempFile = res.tempFiles[0];// 检查文件大小(1MB = 1024*1024字节)限制2MB及以上图片不能上传if (tempFile.size > 2048 * 1024) {wx.showToast({title: '图片需小于2MB',icon: 'error',duration: 2000});return; // 终止执行}this.setData({avatar: res.tempFiles[0].tempFilePath   //将缓存地址赋值})var filePath = res.tempFiles[0].tempFilePath;this.convertToBase64(filePath).then(base => { //这里调用了文件转化方法console.log(base)that.setData({'formData.avatar': base   //这里是将base64的数据进行赋值})}).catch(err => {wx.showToast({title: err,icon: 'error'})});},fail: err => {},complete() {}})},

 以下是将文件转为base64类型的方法

  // 将图片转为base64文件流convertToBase64(tempFilePath) {return new Promise((resolve, reject) => {wx.getFileSystemManager().readFile({filePath: tempFilePath,encoding: 'base64',success: function (res) {resolve(res.data);},fail: function (error) {reject(error)}});})},

传输的数据如下:

 

 在后端只需要使用string类型将数据接收

按照我以下代码的顺序去实现:

首先我们先要有一个将对象带图片加入数据库的sql语句,这里使用的是参数化sql命令

因为图片较大会影响应用性能,所以在这里进行一个文件压缩,如果不需要压缩使用第二张图的方法:

 

如不需要压缩使用以下方法直接转为二进制流:

 如需要压缩,需要使用到的工具类如下:

  /// <summary>/// 图片压缩工具类/// </summary>public class ImageCompressor{public byte[] CompressImageFromBase64(string base64Data, long quality = 70L){// 1. 去除Base64头(如"data:image/png;base64,")//var cleanBase64 = base64Data.Split(',')[1];byte[] imageBytes = Convert.FromBase64String(base64Data);// 2. 加载图片并压缩using (var msInput = new MemoryStream(imageBytes))using (var image = Image.FromStream(msInput))using (var msOutput = new MemoryStream()){// 设置JPEG压缩质量(如果是PNG,调整格式)var encoderParams = new EncoderParameters(1);encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);// 获取JPEG编码器var jpegEncoder = GetEncoder(ImageFormat.Jpeg);// 保存压缩后的图片image.Save(msOutput, jpegEncoder, encoderParams);return msOutput.ToArray();}}private ImageCodecInfo GetEncoder(ImageFormat format){var codecs = ImageCodecInfo.GetImageDecoders();foreach (var codec in codecs){if (codec.FormatID == format.Guid)return codec;}return null;}}

 当转换成功后,我们将转化的二进制流存入数据库

注意数据库中设计字段一定要为可变长的二进制数(这里使用varbinary(MAX)占用的数据库空间也比较大)

 二进制数存储方法如下,其他的数据就使用AddWithValue方式存储

如果你是循环增加的,需要在以下代码前面增加cmd.Parameters.Clear();防止其他问题报错

cmd.Parameters.Clear(); //清除参数

 将图片存入数据库后数据如下:

接下来我们需要取出数据进行展示,以下是我们通过sql将数据取出来后,取出的数据要转为byte[]的类型,然后在将byte[]类型转为base64String的数据返回给前端(同样是赋值给string类型)

 在我们获取到数据返回给前端后,我们需要将传过来的base64数据通过以下方法进行转化(转化的结果只能作为图片的存储地址,所以有以上结构进行赋值)

const dataURL = `data:image/png;base64,${dataItem.avatar}`;

赋值完成后,就可以显示出图片了

 

http://www.xdnf.cn/news/735373.html

相关文章:

  • 深入理解数组索引:原理、应用与优化
  • Centos7系统下脚本一键部署LAMP环境
  • 响应式原理
  • Java异常与错误:核心区别深度解析
  • Kafka多线程Consumer
  • harmonyos实战关于静态图片存放以及image图片引入
  • VSCode Trae Cursor 显示多tab界面
  • intra-mart执行java方法笔记
  • spring openfeign
  • AWS云创建安全审计用户组
  • TIDB创建索引失败 mkdir /tmp/tidb/tmp_ddl-4000/1370: no such file or directory.
  • NHANES指标推荐:CQI
  • ESP32对接巴法云实现配网
  • 线路板厂家遇到的PCB元件放置的常见问题有哪些?
  • 内核进程基础
  • 界面控件DevExpress WinForms中文教程:Banded Grid View - 如何固定Bands?
  • 《 PyTorch 2.3革新:torch.compile自动生成CUDA优化内核全解》
  • 鸿蒙OSUniApp页面切换动效实战:打造流畅精致的转场体验#三方框架 #Uniapp
  • Go语言结构体:数据组织的艺术
  • 网络犯罪分子利用虚假ChatGPT安装程序实施攻击
  • 【Go语言】Fyne GUI 库使用指南 (面向有经验开发者)
  • XUANYING炫影-移动版-智能轻云盒SY900Pro和SY910_RK3528芯片_免拆机通刷固件包
  • PHP中文网文章内容提取免费API接口教程
  • JavaScript中的命名导出(暴露)
  • yolov8添加注意力机制
  • 避免空值判断
  • Fluence (FLT) 2026愿景:RWA代币化加速布局AI算力市场
  • 一、Python 常用内置工具(函数、模块、特性)的汇总介绍和完整示例
  • Go 中 `json.NewEncoder/Decoder` 与 `json.Marshal/Unmarshal` 的区别与实践
  • C++学习-入门到精通【10】面向对象编程:多态性