将一个黑白二值的图像存入数据库,有什么好建议?

2014-05-22 20:03:05 +08:00
 andybest
图片样例:
只有黑白两色,图片(PNG格式)大小在200字节左右
我将图片转换为0与1的文本,看是否能降低尺寸,结果该 文本.length 有1k+...
除了直接将该图片以二进制形式存入数据库,还有没有什么更好的办法?
3746 次点击
所在节点    问与答
24 条回复
czheo
2014-05-22 20:15:12 +08:00
转16进制? 比如在bash里面输入
printf '%x\n' "$((2#10101010100011101111101))"
66CCFF
2014-05-22 20:16:52 +08:00
二进制当然比文本小一些…
还想优化的话,试试对binary压缩一下?把连续超过8位的1或者0计数起来。
andybest
2014-05-22 20:17:03 +08:00
@czheo 谢谢,转为0与1的文本长度为891:

000000000000000111111111000000000
000000000111000000000000000000000
000111000000000111000111111000111
000000111111000111111000111000000
111111000111111000111000000111000
111000111111000000000000000111000
111111000000000000000111000111111
000000000000111000000000111000000
000000111000000000111000000000000
111000000000111111111111000000111
111000000111000111000000100000000
000111000111000000100000000000111
000111000111100000000111000111000
000111100000000111000111000000111
100000000111000111000000000000000
111000000000111000000000000111000
000000111000000000000111000000000
111000000000001000000111000111000
000000001000000111000111000000000
001000000111000111000111000001000
111000111111111111000001000111000
111111111111000001000111000000000
111111000001111000111000000111111
000001111000111000000111111000001
111000111000000111111111111000000
000111000111111111111000000000111
000111111111111000000000111000111

这串东西即使转为 16 进制长度也不会低于图片本身的200字节吧?
andybest
2014-05-22 20:19:31 +08:00
@66CCFF 谢谢,也就是说,我直接把图片存数据库里就得了?没什么简单的方案可以节约更多空间了?
vibbow
2014-05-22 20:20:24 +08:00
先gz一下再存呢
andybest
2014-05-22 20:26:51 +08:00
@vibbow 谢谢,这个图片 265 字节,gz 后 176 字节,
除了更耗 CPU 的压缩方式外,还有能比176更低的方案吗?
wingoo
2014-05-22 20:26:52 +08:00
01压缩应该比较好压吧
写个算法,0/1大于1个的后面用数字标示,数字个数含有01用其他字符代替
试试
forexi
2014-05-22 20:27:55 +08:00
图片的数量很大吗?
如果不是很大的话,不用转换,直接把png图片的内容存入数据库,也才200字节左右。或者使用压缩的png(好像可以压缩),简单做。
andybest
2014-05-22 20:32:22 +08:00
@wingoo 谢谢,这个压缩方案对大量连续的黑白有效,但这种均匀散布的黑白图压缩后文本长度仍然远大于 200 字节
forexi
2014-05-22 20:33:06 +08:00
再说明下,不用读图片的像素,直接把png文件的内容存入数据库。回头从数据库读出来,再解析png。想数据量小的话,尝试压缩png格式。
andybest
2014-05-22 20:34:40 +08:00
@forexi 谢谢,现在我就是这样做的,PNG图片本身也已经压缩到最优了,但我想有没更好的储存方案来针对这种图片
forexi
2014-05-22 20:37:44 +08:00
@andybest 如果类似二维码的话。考虑用一位二进制代表一个色块?
PhilCai
2014-05-22 20:39:57 +08:00
纯外行提个不负责任的意见:那个二进制既然有一串01并且很多是连续的,干脆用类似压缩矩阵来存呢。。。
andybest
2014-05-22 20:44:35 +08:00
@forexi 不是二维码,类似迷宫图,有2px粗的条,也有1px的

@PhilCai 关键是连续性不够,导致单纯去压缩0101010文本效果很不理想,比如文本:000111用33代表就可以了(只是个简单假设不是真正压缩算法),但010101这用这个算法去压缩就甚至会比之前的文本还大了
czheo
2014-05-22 21:03:46 +08:00
Sunyanzi
2014-05-22 21:15:48 +08:00
图片样例看起来略奇怪 ... 大量的 3x3 像素的黑白格子 ... 感觉应该有规律可循 ...

如果是类似二维码的图片可以直接用摘要算法搞定 ...

如果是单纯的黑白图 ... 存成只有黑白两色的 gif 应该会小于存成 png ... 不确定 ...

论算法的话 ...最容易想到的也是最通用的办法就是二值化然后八位一分组存成 ASCII ...

以你的例子来看 ... 891 转化后的长度是 112 ... 小于原始图片的两百字节 ...

如果二值化之后的结果有大量的连续值 ... 那么可以用如下的算法 ...

最终结果的奇数位代表连续 0 的个数 ... 偶数位代表连续 1 的个数 ...

如果有连续的 0 或者 1 超过 255 个 ... 后一位接 0x0 ... 然后继续分隔 ...

这两种方式不一定哪种会更优 ... 要看具体的数据特征 ... 以 3F 贴出数据的前八行为例 ...

二值化存储的结果是 33 个字节 ... 连续算法的结果是 43 字节 ...

按照结果做出的 33x8 的图片不管存成什么格式都要上百字节 ...

我的测试结果就是如此 ... 供参考 ...
paulw54jrn
2014-05-22 21:16:52 +08:00
楼主可以试下 bwt + 上面说的run-length-encoding.
bwt可以把所有的相同字符归类在一起,然后再做run length encode就会有高效很多.

http://en.wikipedia.org/wiki/Run-length_encoding
http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform
79bxh9b
2014-05-22 21:18:16 +08:00
如果自定义图片格式的话
你这张图33x27,33*27/8,每个字节存8个像素,要112字节,再加上恢复成图像需要宽高信息,如果尺寸在256以下的数值1个字节就能表示,114字节是极限了。
然后以二进制存数据库

想省力的话换gif格式,gif支持黑白模式,150字节
66CCFF
2014-05-22 21:28:52 +08:00
@andybest 最省事而且靠谱的办法,把二进制gz一下丢数据库就好了。
Tianpu
2014-05-22 22:20:02 +08:00
@czheo 给出数据亲测可以做到129哇

用尽ASCII表可能有隐患 不过可以再设计更好的方法 比如如果片段值是小于64的就再搞一次 感觉平均做到100之下应该可以的

function encode($str){
$r = '';
$temp = str_split($str,7);
$count = count($temp);
for($i=0;$i<$count;$i++){
if($i==$count-1){
$r.= ' '.$temp[$i];
}
else{
$r.= chr(base_convert($temp[$i],2,10));
}
}
echo strlen($r);
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/113816

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX