今天在改进 iText 上传前压缩大图的功能。其中,百度、腾讯、Google 等各家 OCR 服务对上传的图片尺寸都有要求、也都要求对图片进行 base64 压缩。可这要求跟要求可就不同了。
为什么实际大小与宣称大小不一致呢?
既然 base64 会带来计算上的麻烦,为什么不直接使用解压后的图片大小呢?没错,Google 就是这么干的。你无需考虑 base64 带来的尺寸增加,也无需考虑一个字符串到底占几个字节,只要原图是 4 MB 以下即可
从这一点上看,服务接口的素质(公司的节操)顺序为:
Google
> 腾讯
> 百度
哎,我真是看不出黑百度或者腾讯对我有什么好处,只是多次试错后过来发个牢骚。
对,base64 编码我写成了压缩,这点可以喷;
对,「计算方式」是我根据测试结果逆推的,看起来是有点问题,这个可以喷;不过「实际可用大小」是我实测的结果,这个是准确的。
以上,请尽情喷、吐槽、BS;吐爽了,可以往下看;不然请继续。
不过,「base64 编码后大小是 4 MB」,请问这 4MB 如何计算?
是 4MB 「个」编码后的字符串?测试结果不是;是每个字符占 2 个字符吗?百度的测试结果是(虽然这并没太多道理)。 还请行家指个点,这个 4MB 到底怎么比较?最好解释清楚后再 BS 我,显得更专业。
所以,我最想吐槽的是这一点:为什么不直接使用原图来判定、而要用 base64 的这个说不清楚的大小?平白给开发者带来这样的麻烦?只是为了服务器减少一次解码的开销?我只能这么想。
「宣称图片大小」这个用词不对,我认。 base64 是编码不是压缩,我懂,不然我也不会说到 1/3 这个词。你要揪着用词不放,你开心就好。
百度和腾讯文档里提了 base64 编码的大小,我绝逼知道。我发贴是为吐槽那些不用图片原始大小、而非得用 base64 编码大小来比较的服务。我吐槽,是因为我花了不少时间试错,不爽,所以要吐槽。
如果你觉得我是来秀下线的、或者觉得我没有资格在 V 站吐槽我认为不爽的事情、或者是为 iText 上线前宣传造势,欢迎在 V 站 Block 我:点我的头像,右边有个 Block. 这样,可以节约你我的时间。谢谢。
最后,继续欢迎有高手能明确指出 4MB 的 base64 到底应该如何比较?最好你试试后再来;因为我试过多次,跟想当然的并不一样,谢谢。
我就问一句:多大(字节)的图片,可以上传至百度、腾讯 OCR 服务?
如果你知道,欢迎告诉我。
我知道,4MB 的图片可以上传至 Google;我自己试过 3.9MB,可以的。
1
kunluanbudang 2017-11-21 23:55:49 +08:00
还有国内公司的 REST API, 用户体验是..
|
2
tlday 2017-11-22 00:33:32 +08:00 via Android 2
看不懂"一个字符如'a'占几个字节"这条。base64 不就是拿 4 个字节表示原来三个字节表示的东西,用 64 个可见字符映射了 256 个全量字符,不能被三整除的余位补等号的算法么,怎么还有'a'占几个字节这一说。这 64 个可见字符都是 ascii 标准可见字符,在 utf8 和 ascii 下编码和占用空间不也是一样的么,怎么还有百度用 2,腾讯用 1 之分?
|
3
OldPanda 2017-11-22 03:41:10 +08:00
不禁想起两年前用豆瓣 API 搞了个图片同步工具,然而不久后豆瓣就把 API 关了 ┑( ̄Д  ̄)┍
|
4
Keyblade 2017-11-22 08:12:08 +08:00
应该是
Google > 腾讯 = 百度 |
5
CSM 2017-11-22 08:25:30 +08:00 via Android
第一看到 base64 *压缩*这种说法...
|
6
onlyice 2017-11-22 08:42:32 +08:00
感觉这个有点为黑而黑了。
你觉得像百度 / 腾讯会在意这点大小吗?用 2M 会比 1M 增加很多成本吗?会需要为了宣传而搞一个大一点的数字吗?有什么意义呢。。 这只能说明文档上写得不严谨,还能跟公司挂钩起来,也是有意思 |
7
missdeer 2017-11-22 08:43:58 +08:00 1
第一看到 base64 *压缩*这种说法...+1
|
8
azygote 2017-11-22 08:46:28 +08:00
压缩后体积会变大……
|
9
MrSong0607 2017-11-22 08:48:47 +08:00
第一看到 base64 *压缩*这种说法...+2,base64 不是编码么
|
10
xiaojunjor 2017-11-22 08:52:04 +08:00
“首先,base64 压缩后,得到的大小会增加约 1/3 ”。。。压缩后大小增加了???
|
11
leeg810312 2017-11-22 08:53:55 +08:00 via Android
百度和腾讯没有在文档说清大小是 base64 格式,谷歌说的是图片文件大小,为黑而黑,而且还说错了,base64 是压缩?
|
12
xsd3169 2017-11-22 08:54:33 +08:00
第一看到 base64 * 压缩 * 这种说法...+3。。。确定不是 ** 膨胀 **吗?
|
13
q409195961 2017-11-22 09:00:34 +08:00
第一看到 base64 *压缩*这种说法...+4
编码:aGVsbG8lMkN3b3JsZA== 明文:hello,world 压缩了?? |
14
onlyice 2017-11-22 09:02:01 +08:00 7
百度的文档[1],清晰地写着「 base64 编码后大小不超过 4M 」;腾讯的文档[2]写着「原始图片的 base64 编码数据(解码后大小上限 1MB,支持 JPG、PNG、BMP 格式)」。
楼主我不得不说这文章体现的是你的节操? [1] https://cloud.baidu.com/doc/OCR/OCR-API.html [2] https://ai.qq.com/doc/ocridcardocr.shtml |
15
marcong95 2017-11-22 09:11:09 +08:00 via Android
@onlyice 2M 跟 1M 翻了个倍,成本也翻倍,作为一家巨头公司成本翻倍不在意?多了 50%的利润空间根据邓宁格的说法就已经引起积极的冒险了。资本是逐利的,国内大型公司没节操的事情还见得少?
不过呢,这件事上好像并不怎么能黑,我看了下他们的文档,百度写的是 base64 字符串小于 4096K,腾讯写的是图片小于 1M,跟楼主所说的一致,两者好像都没有什么不严谨的地方。 |
17
mengzhuo 2017-11-22 09:13:56 +08:00 via iPhone
看到 base64 压缩之后就不想看后面,直接看评论
|
18
xfspace 2017-11-22 09:15:05 +08:00 via Android
楼主想黑百度腾讯,没想到被自己智商秀了一波
|
19
onlyice 2017-11-22 09:16:58 +08:00
@marcong95 一个 OCR 服务能有多少成本?又不是全部服务都翻一倍。但这不是重点,重点还是人家文档已经写清楚了,楼主强行表示对方夸大
|
20
DOLLOR 2017-11-22 09:23:39 +08:00
此前见过说 base64 “加密”的,base64 “压缩”倒是第一次见……
|
21
abujj 2017-11-22 09:39:00 +08:00 via iPhone
谷歌 API 地址能发下看看吗? 楼主
|
22
bzzhou 2017-11-22 09:50:22 +08:00 1
base64 压缩,呵呵
|
24
BBCCBB 2017-11-22 10:01:28 +08:00
|
25
xiao17174 2017-11-22 10:15:21 +08:00 4
显然楼主对于为什么用 base64 完全不懂,对于字符编码,字节,位什么的更是从来没有涉及过.
由此可以推断楼主在成为程序员后就一直从事高级语言的相关工作. 建议楼主可以适当下潜,多了解一些基础的东西. 最后解答一下楼主提出来的"请问这 4MB 如何计算?" 答:不要把字符编码和数据大小混在一起. 一个字符'a'占用几个字节是你自己决定的,当你声明你发送的是以 ascii 编码的数据时,它占一个字节.当你声明你发送的是以 chibaolechengde 编码的数据时,它可以是占 10 个字节. 既然人家都说了是要 base64 后的数据发送,那么显然是 ascii 编码.即编码后的数据,每一个可见的字符,如'A','='都是占用一个字节. |
26
keenwon 2017-11-22 10:17:20 +08:00
base64 是压缩?
|
27
xiao17174 2017-11-22 10:20:40 +08:00 2
另外,多一次 base64 编码在麻烦程度上来说,对谁都没有好处.服务器在拿到你 base64 的数据后,必然是要做一次反编码来获取真实数据的.只是 base64 可以归一化所有的二进制数据到 ascii 码上,从而变成更通用的 string.
|
28
keenwon 2017-11-22 10:20:51 +08:00
歪个楼,MD5 算加密吗?
|
29
xiao17174 2017-11-22 10:24:54 +08:00 2
@keenwon 是摘要算法.可以理解一个 md5 是一篇文章的中心思想.
加密成立的前提在我看来是可以解密,但是我们显然无法从中心思想反推全文,所以不算. |
31
ioth 2017-11-22 11:20:10 +08:00
说明咱天朝人会过日子,节省
|
32
Youen 2017-11-22 11:20:34 +08:00
阿里的我测试过,文档说图片大小不超过 1.5MB, 我用 1.47MB 文件 base64 编码后约 1.9MB 可以识别
|
33
sneezry 2017-11-22 11:26:17 +08:00
其实 API 更严格的限制并不让人不快,即使百度最大图片支持 1.5MB 也没什么问题。问题是为了显示自己有优势而进行虚标,这在实际使用时会出现诡异的问题。
|
34
zwh2698 2017-11-22 11:31:19 +08:00 via Android
顶,兄弟
|
35
jyf 2017-11-22 11:34:37 +08:00 1
从吐槽上也能看出一个人的素质 这不就是百度图省事 在上传服务器上做了个请求体大小的限制么 这种也要罗嗦一堆也真是
|
36
nine99 2017-11-22 11:40:34 +08:00
itext 还不发布吗
|
37
veightz 2017-11-22 13:23:30 +08:00
一个 API 也许能代表某个开发,但是代表不了一个公司
|
38
mikulch 2017-11-22 13:54:58 +08:00
国外的公司,在人性化,细节等方面本身就完爆中国的公司
从制造业就能看出来了。 |
39
zhouyg 2017-11-22 14:51:11 +08:00
百度最喜欢搞虚假的东西,果然连技术人员的骨子里都是腐蚀透了
|
40
moonsola 2017-11-22 15:06:19 +08:00
|
41
schema 2017-11-22 15:59:12 +08:00
标题日常哗众取宠
|
42
st2udio 2017-11-22 16:36:37 +08:00
原始图片的 base64 编码数据(解码后大小上限 1MB,支持 JPG、PNG、BMP 格式)
base64 编码后大小不超过 4M,最短边至少 15px,最长边最大 4096px 有不对的宣传吗?不懂。。 [为什么实际大小与宣称大小不一致呢?] 还只是为了推广你的软件,所以要 |
43
so898 2017-11-22 17:00:40 +08:00
腾讯那个确实有点难找,百度这个可是重复声明了 14 遍啊~~~~~~
估计楼主的母语是英语吧,看英文仔细程度大于看中文仔细程度 |
44
yuriko 2017-11-22 17:04:10 +08:00
当喷国内公司变成政治正确的时候,不懂瞎说的也有底气了……
|
45
MushishiXian 2017-11-22 17:26:45 +08:00
v2 太可怕了...
|
46
Charkey 2017-11-22 17:30:03 +08:00
so 世界好可怕,到处 pen
|
47
quietjosen OP @xiao17174 在这些回复中,你的最有技术含量。
不过,事实上,如果发送 3MB 个字符(按你所说是 ASCII 编码)的 base64 编码的图片给百度,百度是会报错的,说图片尺寸不对。我也只能推测 http 请求是按 utf8 传送、每个字符占 2 位,所以要 /2 ;不然,我是没办法和事实对应。 |
48
xiao17174 2017-11-22 18:12:30 +08:00
@quietjosen utf-8 是一种编码规范,实际上它是可变长的,并不是所谓的每个字符占 2 字节(不是位).而且正如楼上某位说的,utf8 是兼容 ascii 的,也就是说针对'a''A'这种,utf8 也规定只占用一个字节.可能我说这些你会听得一头雾水.
如果有空可以自己了解一下. 至于你说的猜测,我也有几个猜测. 1.你以为的 3MB 个字符其实并不是真的 3MB,实际的字节数已经超过 4MB,你可以看下你的 context-length 上标识的是多少. 2.如返回值所说,你传的图片的尺寸真的超出 15px*4096px 限制. 3.你传的数据在某个过程中被截断了.可能是你这边,也可能是在服务器那边,错误的数据导致了百度解析图片出错,而服务端的返回值延用了尺寸不对的错误码.本质上是数据解析(读取图片)出错. |
49
xiao17174 2017-11-22 18:13:58 +08:00
我为什么这么空....伤脑筋啊...
|
50
quietjosen OP @xiao17174 谢谢回复。
1. 对,我说的是 3MB 个字符;如果确实是用 UTF8 编码、英文字符占 1 个字节,那按道理应该是 3MByte 了。 2. 图片没有超出尺寸限制 3. 应该不是,因为如果解析出错,返回的错误是不同的。 有时间,我测试下连续的尺寸,比如 2.01MB/2.02MB/…/3.00MB,看哪个尺寸开始不行。 问题就在于:为什么要让每个接入服务的开发者,花这么无谓的时间、做这种无谓的试错?看看人家 Google,只要原图 OK 就行。 |
51
xy90321 2017-11-22 19:34:01 +08:00 1
@quietjosen 如果照着 API 文档开发也能算试错的话,我建议你自己去发明所有轮子这样就不存在试错了
别人 API 文档里写的那么清楚了,哪里存在试的过程了。。。 要吐槽 API 不够人性化那就请明明白白吐槽 API 不够人性化 非要整点素质啊气质啊什么的,上升到百度腾讯就是渣渣,看我大谷歌秒杀全场 再加上顶楼里那简直可以称为之污蔑诽谤与事实完全不符的描述 这就是所谓的带节奏失败反过来装人畜无害吗? |
52
sicongwang 2017-11-22 21:02:11 +08:00
为黑而黑, 已 block
|
53
leonzoe 2017-11-22 23:25:01 +08:00
只能说同情楼主了.楼上一群人既没试过,也没给个公式算一下,这就开始喷了,斯阔以.
|
54
inoris 2017-11-23 00:06:27 +08:00
同情楼主。
|
56
Technetiumer 2017-11-23 01:38:42 +08:00 via Android
這說明了 Google 更人性化
節省了你的時間去計算 base64 後大小 評論裡有人說樓主為了噴爾噴 那我也回复不要為了噴爾噴 |
57
chnyang 2017-11-23 08:01:50 +08:00 via Android
@Technetiumer 指出楼主为喷而喷并不算喷
|
58
dazui 2017-11-23 08:08:34 +08:00
国内都是参考切糕的卖法,只卖 10 元,然后你要算算是 1 克、1 块还是 1 斤
|
59
atcdef 2017-11-23 09:17:21 +08:00
楼上有很多抠字眼,base64 压缩,这样说应该明白楼主说的是编码,至于死抠“压缩”两个字么。
|
60
root123 2017-11-23 09:23:26 +08:00
同情楼主。+1
很喜欢 LZ 的系列 APP,都很方便实用。 而且在开发 APP 的过程中,楼主也经常分享技术、运营的相关经验,很不错啊。 |
61
Tokin 2017-11-23 09:41:23 +08:00
google 明显更人性化啊,虽然百度和腾讯文档写的很清楚,但是明明可以做的更好的。大概这就是气质???
|
62
pathbox 2017-11-23 09:46:16 +08:00 via iPhone
讲真 API 文档这一类,是一家互联网科技公司的 “门面” 。大家共勉
|
63
jimrok 2017-11-23 10:23:06 +08:00
google 确实比百度好不少,接口文档就是计算机里的电路板,看过苹果的,再看其他的机器就知道差距是全面的。
|
64
XYxe 2017-11-23 10:29:58 +08:00
https://i.loli.net/2017/11/23/5a162fb434cdf.png 这是一个 2.48MB ( 5752*4824,超过要求了)的图片,base64 以后是 3.31MB。
时间有限,只测试了百度的 API。代码: ```python import requests import base64 rsp = requests.post('https://aip.baidubce.com/oauth/2.0/token', data={'grant_type': 'client_credentials', 'client_id': API_Key, 'client_secret': Secret_Key}) token = rsp.json()['access_token'] f = open('sbpen.png', 'rb') d = f.read() b64data = base64.b64encode(d) rsp = requests.post('https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic', data={'access_token': token, 'image': b64data}) print(rsp.json()['words_result']) ``` 输出: [{'words': '为什么实际大小与宣称大小不一致呢?'}, {'words': '首先,base64 压缩后,得到的大小、会增加约 1/3'}, {'words': '·进一步,base64 是使用字符串表示的。那么 ,一个字符串如\'a"占几个字节呢?看起来百度是使用 2,腾讯是使用 1'}, {'words': '综合起来,就是上面看到的缩水版大小'}, {'words': '另外,百度要求图片最大分辨率为 409 6*4096;而其他 2 家则无此要求'}, {'words': '既然 base64 会带来计算上的麻烦,为什么不直接使用解压后的图片大小呢?没错, Google 就是这么干的。你无需考虑'}, {'words': 'base64 带来的尺寸增加,也无需考虑一个字符串到底占几个字节,只要原图是 4MB 以下即可'}, {'words': '从这一点上看,服务接口的素质(公司的节操)顺序为:'}, {'words': 'Goog1e>腾讯>百度'}, {'words': '第 1 条附言·1 天前'}, {'words': '哎,我真是看不出黑百度或者腾讯对我有什么好处,只是多次试错后过来发个牢骚'}, {'words': '对,base 64 编码我写成了压缩,这点可以'}, {'words': '对,「计算方式」」是我根据测试结果逆推的,看起来是有点问题,这个可以喷;不过「实际可用大小√」是我实测的结果,'}, {'w ords': '这个是准确的。'}, {'words': '以上,请尽情喷、吐槽、Bs;吐爽了,可以往下看;不然请继续。'}, {'words': '不过,「 base64 编码后大小是 4MB 」,请问这 4MB 如何计算 ?'}, {'words': '是 4MB 「个」编码后的字符串?测试结果不是;是每个字符占 2 个字符吗?百度的测试结果是(虽然这并没太多道'}, {'words': '理)。还请行家指个点,这个 4MB 到 底怎么比较?最好解释清楚后再 BS 我,显得更专业'}, {'words': '听以,我最想吐槽的是这一点:为什么不直接使用原图来判定、而要用 base64 的这个说不清楚的大小?平白给开发 者带'}, {'words': '来这样的麻烦?只是为了服务器减少一次解码的开销?我只能这么想。'}] 不知道你的 1.5MB 是怎么得出来的。 另外,计算一个字符串占用空间很难吗? |
65
quietjosen OP @XYxe 首先,谢谢你这么有技术含量的回复。
1. 我试了你的代码和图片,可以上传、识别,没有问题。 2. 我试了你的图片和我的代码,依然提示图片大小不正确。 为什么呢? 我检查了下,因为你用的是普通的识别: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic 我用的是高精度识别: https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic 如果, - 你的代码改用高精度识别,失败,提示图片大小不正确。你可以试试。 - 我的代码改用普通识别,成功 依然是几个事实: - 百度的文档( https://cloud.baidu.com/doc/OCR/OCR-API.html )里并没有说高精度识别的尺寸应该比较小。 - 为什么 5752*4824 明明已经超出了百度规定的「最长边最大 4096px 」,普通版依然能正确识别? 我就不推导什么结论了,看官自己心里自有判断。 |
66
XYxe 2017-11-23 11:22:40 +08:00
@quietjosen #61 这个错误提示是因为图片尺寸太大了。
https://i.loli.net/2017/11/23/5a163e6d996a8.jpg 这个 2.95 MB,4000*3356,base64 以后大概 3.9MB 。 高精度识别,你试试? |
67
quietjosen OP @XYxe 我用你的图片试了,高精度可以识别。
那看来上一张图说明的问题是:通用文字识别对最大分辨率的判断不准确,而高精度识别是则是准确的。 另外,百度的错误码并没有区分是图片太大,还是分辨率太大,是混在一起的,不太好: 216202 image size error 上传的图片大小错误,现阶段我们支持的图片大小为:base64 编码后小于 4M,分辨率不高于 4096*4096,请重新上传图片 到目前,我奇怪的是,我之前确实出现过分辨率正确、图片尺寸太大,也返回 216202 这个错误。这次用你的图试,就没出现。之后有时间多造些图试试。不过目前打算中文抱腾讯的大腿了,因为感觉腾讯对英文的识别比百度好。国外用户抱 Google 大腿。 |
68
Kisesy 2017-11-23 12:56:37 +08:00
@quietjosen 你就不能发个你不行的例子,让别人试一下吗
|
69
quietjosen OP @Kisesy 你这个问题问的很好。
首先回答你的问题:我应该是无法提供这样的图了。具体请向下看: 我在试着做出这样的图时,可能发现了问题。比如,当我在压缩一张 2000*2000、大小为 5,217,759 bytes 的图时,当「压缩」为 2187*2187、大小为 2,397,638 bytes 时,我觉得,恩,图片肯定对了,base64 后大小也没问题。于是就去上传到百度,发现还是得到 216202 这个错误。我想,分辨率没有问题,自然是图片大小比较出现问题。恰好,当继续压缩后(比如文中提到的 1.5MB )时,可以上传并成功识别了。 所以,我会得出文中开头的推论:可能跟 base64 大小及编码比较有关。 但,你在让我提供这样的图时,我就把压缩过程中、存在于内存中的图片输出出来,结果一看,虽然大小确实是 2,397,638 bytes,但分辨率却是:4374*4374,超出了百度 4096*4096 的限制,所以出错了。 奇怪,明明是压缩了,为什么分辨率反而提高了? 我又用工具查看图片信息,发现 DPI 是 144: 这应该就是原因了。原图应该是 72 DPI 的,而由于我通过 NSImage 缩放、在用 NSBitmapImageRep 取 jpeg 格式的 Data 时,估计 Mac Book Pro 使用 144 来计算 pixels,也就是,把 2187*2187 乘以 2,变成了 4374*4374。 于是这些计算都在内存中,我确实没有发现;直到你让我提供这样的图,还得谢谢你的问题。 所以,我应该收回对百度的批评,并对百度可能的名誉损失道歉。 不过,我依然保留对百度此 API 保留意见: - 如果百度返回错误区分图片大小和分辨率错误,我就可以很容易地发现问题。 - 如果百度不限制分辨率( Google 和腾讯均未限制),也就不会出现问题。 |
70
quietjosen OP 更正:上楼中的 2000*2000、大小为 5,217,759 bytes 的图,数据不正确,应该是 3000*3000、大小为 13,452,222 bytes ;多次测试过程中,数据贴错了,抱歉。
|