尝试在前端图片上传前压缩 Base64

2016/05/25 | 2分钟阅读 | 更新于 2016/05/25

图片上传是件挺麻烦的事情,表单上传会刷新,虽然有 iframe 可以避免页面刷新但是还是挺麻烦,ajax 上传 base64 倒是个不错的办法,可惜图片小点还好,于是冒出了个压缩下 base64 编码的想法。

在线给一张图片编码,复制下来看了下编码的结构,目测着大概有些字符串会重复出现多次,于是要找长字符串里重复了比较多次数的又比较长的子字符串,然后替代成比较短的字符。 因为不太容易处理子字符串交叉的问题,所以只做了一组子字符串(最少四个字符,最少出现五次)的替换,替换为 ‘#1’ 。

结果在比较简单的图片(背景几乎为单色,图案很少集中在中心)上效果很棒,在尝试的图片里,效果最好的替换后长度可以缩短到原来的60%左右。但是对内容变化较大的照片,不管是几百k的 jpg 还是2MB多的 png,压缩后长度也就在 99.9%,虽然多替换几组的话效果也许会好些,或者可能有更长的未匹配到的字符串,但是感觉意义不是不大。

代码贴一下:

var Str = "Base64长字符串";
var Min = 4;
var _len = 5;
var _id = Str.length - _len;
var _str = Str.slice(_id, _id + _len);
var obj = {
  len: _len,
  id: _id,
  str: _str,
  find: [],
};
console.log(obj);
var Key = 1;

while (Key == 1) {
  console.log(obj);
  obj.str = Str.slice(obj.id, obj.id + obj.len);
  obj.str = obj.str.replace(/\+/g, "\\+").replace(/\//g, "\/");
  var _reg = new RegExp(obj.str, "g");
  var _num = Str.match(_reg).length;
  obj.num = _num;
  obj.reg = _reg;
  if (_num > Min) {
    /* 有足量的符合预期的匹配 */
    /* 试图扩张 */

    while (true) {
      var _id = obj.id - 1,
        _str = Str.slice(_id, _id + obj.len),
        _reg = new RegExp(_str, "g"),
        _num = 0;
      if (_id < 0) {
        /* 结束 */
        break;
      }
      // _str = Str.slice( _id, _id + obj.len);
      // _reg = new RegExp( _str, 'g' );
      _num = Str.match(_reg).length;
      if (_num > Min) {
        /*可以扩张*/
        obj.str = _str;
        obj.len = obj.len + 1;
        obj.id = obj.id - 1;
      } else {
        /* 不能扩张 */
        /* 保存当前结果 */
        obj.find.push(obj.str);
        obj.str = obj.str.replace(/\+/g, "\\+").replace(/\//g, "\\/");
        obj._reg = new RegExp(obj.str, "g");
        var _res = Str.replace(obj.reg, "#1");
        console.log(
          _res.length + " / " + Str.length + " | ", // + _res
        );
        obj.per = parseInt((_res.length / Str.length) * 1000) / 10 + "%";
        Key = 0;
        break;
      }
    }
  } else {
    /* 没有符合预期的匹配 */
    /* 前移 */
    if (obj.id - 1 >= 0) {
      /* 可以前移 */
      obj.id = obj.id - 1;
      obj.str = Str.slice(obj.id, obj.id + obj.len);
    } else {
      /* 结束了 */
      break;
    }
  }
}

console.log(obj.per);

© 2026 香蕉引擎故障报告

🌱 Powered by Hugo with theme Dream.

关于

要怎么介绍自己呢,🤔。

很早以前是作为 Web 前端在学习的,但是工作第一年就成为了全干工程师。喜欢尝试各种东西,什么都会一点。

一直很喜欢 Ebiten 游戏引擎 ,特别简洁,用它做过一些小东西,可以查看这个分类 。另外特别推荐这个木鱼 ,是一个相对完整的小玩意儿,包含手搓的一个简单的 UI 框架;支持鼠标和键盘操作;有多语言和主题切换功能;同时支持 Web 端和客户端。它的源代码在 bin16/wooden-fish

主题

网站基于 Hugo,当前使用的是 hugo-theme-dream 主题的修改版 ,根据我的需要,做了一些对 PaperMod 的兼容。

我自己也写过主题 ,但是没有别人写的好看。

正在从我的笔记中往外搬运内容

等待更新:

  • 从《锈湖》中学了些什么东西
  • 我拿 React 写解谜游戏的经过
  • 基于 Pocketbase 的 Pocket Memos
  • 数独!