V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kenneth
V2EX  ›  Python

Python如何快速获得图片的大小,但是不要下载。

  •  
  •   kenneth · 2013-07-08 13:52:25 +08:00 · 10211 次点击
    这是一个创建于 4164 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想提高一下获取图片大小的程序的效率,不想把图片下载,或者读取了才知道大小,大家有没有快速获得图片大小的方法。
    46 条回复    1970-01-01 08:00:00 +08:00
    anjianshi
        1
    anjianshi  
       2013-07-08 13:53:44 +08:00
    是想获得图片的尺寸,还是图片的文件大小?
    yfdyh000
        2
    yfdyh000  
       2013-07-08 13:57:46 +08:00
    kenneth
        3
    kenneth  
    OP
       2013-07-08 14:06:07 +08:00
    @anjianshi
    @yfdyh000
    谢谢,是我没表达清楚,我想知道的是尺寸,就是图片的长宽,但是不知道如何快速得到,不要下载文件。
    phuslu
        4
    phuslu  
       2013-07-08 14:12:12 +08:00   ❤️ 3
    按照 http 标准,完全不下载时不可能的,但是你可以只下载一部分头部。

    之前写过一个根据文件头部读取 imagesize 的单文件 .py
    https://github.com/phuslu/imgsz/blob/master/__init__.py
    楼主你只要喂给它图片的头部下载下来就可以了。
    csx163
        5
    csx163  
       2013-07-08 14:12:26 +08:00
    看了看要求,还是目测吧.

    不下载如何知道呢,靠文件名么?
    kenneth
        6
    kenneth  
    OP
       2013-07-08 14:24:33 +08:00
    @phuslu 要点应该就是你这个,不过你的代码我有点不理解,我再好好看看。
    centerqi
        7
    centerqi  
       2013-07-08 14:40:45 +08:00
    http 有个 head 请求,可以获取文件大小,你可以根据文件大小,得出一个经验值
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
    phuslu
        8
    phuslu  
       2013-07-08 14:42:11 +08:00
    @centerqi HEAD 这个办法基本不可行。你得到是一个 file size, 怎么转化为 "长 x 宽"?
    centerqi
        9
    centerqi  
       2013-07-08 14:50:27 +08:00
    很好算啊,你抓取 几万张图片,把每一个图片的大小和文件大小的关系算出来,你就能得到一个系数,我们每天抓取这么多图片,都是这样弄的,求这个系数很简单的,就是一个 y=ax的问题
    spark
        10
    spark  
       2013-07-08 14:58:21 +08:00
    @centerqi 这种计算方式不靠谱吧...压缩比不一样, 图片尺寸天差地别
    centerqi
        11
    centerqi  
       2013-07-08 15:01:51 +08:00
    好吧,你自己试试就行,一个jpg的图片,5k和 50k的大小会一样吗?
    hengxin196
        12
    hengxin196  
       2013-07-08 15:02:26 +08:00
    用过php的一个 大概是原理是通过获取头 根据头信息获取图片代码
    你可以看看这个 http://hi.baidu.com/vvviop/item/162002149dc26817e3f986c0
    firsthym
        13
    firsthym  
       2013-07-08 15:03:49 +08:00
    读到内存里面不行吗?
    jedyu
        14
    jedyu  
       2013-07-08 15:08:39 +08:00
    @centerqi 那50=25×2还是10×5呢?
    wanderer
        15
    wanderer  
       2013-07-08 15:20:30 +08:00
    @jedyu +1
    dorentus
        16
    dorentus  
       2013-07-08 16:21:45 +08:00
    jpg 用 @centerqi 的方法是最不靠谱的吧……

    同样一张图片,导出时选择的参数不同,可以相差很多的:

    $ identify *.jpg
    0.jpg JPEG 1280x720 1280x720+0+0 8-bit sRGB 126KB 0.010u 0:00.000
    100.jpg[1] JPEG 1280x720 1280x720+0+0 8-bit sRGB 1.185MB 0.000u 0:00.000
    50.jpg[2] JPEG 1280x720 1280x720+0+0 8-bit sRGB 280KB 0.000u 0:00.000
    est
        17
    est  
       2013-07-08 17:24:40 +08:00
    @centerqi 这个是你自己YY出来的吧。同一张jpeg,同一个尺寸,肉眼视网膜可以分辨完全一样的图片:

    用不同scan, quant table, bit depth, color space, PPI 这些参数都能把你爆出翔。
    lichao
        18
    lichao  
       2013-07-08 17:28:26 +08:00
    @centerqi 不可能靠谱吧
    yangg
        19
    yangg  
       2013-07-08 18:04:24 +08:00
    @phuslu 为什么本地文件调用cStringIO.StringIO之后, 结果会出错?
    phuslu
        20
    phuslu  
       2013-07-08 18:25:34 +08:00
    @yangg 请试下 tests 目录的代码是否能够运行,如果跑成功的话,请照那些代码来写。
    pubby
        21
    pubby  
       2013-07-08 19:53:40 +08:00
    根据各种图片格式,一般只要前面几十个字节就能得到 width ,height数据,不需要下载整张图。

    以前拿php的getimagesize()的源代码改过一个的,识别算法都在里头。
    guangwong
        22
    guangwong  
       2013-07-08 20:35:25 +08:00
    读出文件头来就完了= =
    likuku
        23
    likuku  
       2013-07-09 01:25:37 +08:00
    @centerqi 前两天就搞出来1
    M和193K的jpg还真一样长宽的...同一张图。
    centerqi
        24
    centerqi  
       2013-07-09 10:26:55 +08:00
    最好用数据说话,你去淘宝抓取 50w张图片,然后用这种方法去解决,准备率和招回率看能达到多少?
    不要举几个特殊的例子,按你们的说法,做图片相似性计算,图片提取就完全没法做了,因为都会有 bad case.
    love
        25
    love  
       2013-07-09 10:55:54 +08:00
    django源码里面有读文件头得图片长宽的代码段(用到了PIL),具体在图片字段代码这里
    est
        26
    est  
       2013-07-09 10:57:13 +08:00
    @centerqi 你家的相似性计算可以直接通过 content-length 搞定?跪求代码demo。

    长宽是二维矢量,长度是一维标量啊大哥。
    centerqi
        27
    centerqi  
       2013-07-09 11:11:02 +08:00
    楼上好好读读文字,我是用这种方式去做相似计算吗?我是举一下列子,就是通过大量的数据,能训练机器,去找到这个系数。
    phuslu
        28
    phuslu  
       2013-07-09 11:13:03 +08:00
    @centerqi 汗,找到所谓“系数”之后呢, 你莫非认为所有的图片的长宽比是一样的?
    centerqi
        29
    centerqi  
       2013-07-09 11:17:06 +08:00
    用content-length去做相似计算,你这是什么思维啊? 不要误解有木有,把话读完读懂再来喷,好不好?
    我很喜欢你这种思维,欢迎私喷,我的邮箱
    \u0063\u0065\u006E\u0074\u0065\u0072\u0071\u0069\u0040\u0067\u006D\u0061\u0069\u006C\u002E\u0063\u006F\u006D
    centerqi
        30
    centerqi  
       2013-07-09 11:18:50 +08:00
    @est \u0032\u0039\u0030\u0035\u0036\u0030\u0035\u0033\u0032 我的qq,私聊
    phuslu
        31
    phuslu  
       2013-07-09 11:20:13 +08:00
    @centerqi 别回避我的问题。
    ps: 另外你这个所谓 bad case 不是你声称的很少见,而是很常见。
    phuslu
        32
    phuslu  
       2013-07-09 11:20:55 +08:00
    @centerqi 晕,我以为你在和我说话。。。
    binux
        33
    binux  
       2013-07-09 11:20:56 +08:00
    @est 当你面对数以千计的数据量的时候,确实就是这么做的
    centerqi
        34
    centerqi  
       2013-07-09 11:26:11 +08:00
    @binux 我刚才仔细看了一下提问者的问题,可能我们理解都有误差,我是用我的职业思维去解决,提问者的想法是用什么简单的办法,快速获取图片大小,而我们想到的就是 DL,ML之类的,所以会有误解。
    phuslu
        35
    phuslu  
       2013-07-09 11:29:15 +08:00
    @centerqi 楼主的需求我也做过,所以才写出来 imgsz 这个库。
    一般来说获取远程图片的分辨率之后,接下来的处理是展示或者分类。
    展示的话,一般就是瀑布流。分类的话,就是按不同的长宽比分类(16:9, 4:3)等等。
    前者典型的应用就是 BT 工厂, 后者的话,各种壁纸站点。
    binux
        36
    binux  
       2013-07-09 11:34:16 +08:00
    @centerqi 你是WD的?
    centerqi
        37
    centerqi  
       2013-07-09 11:35:15 +08:00
    @phuslu 不错,这种思维确实有可取之处,并且会精确不少,想了解一下,一般图片的头有多少字节,这个是标准的吗?
    centerqi
        38
    centerqi  
       2013-07-09 11:36:32 +08:00
    @binux 这个称呼大高雅了,用内部的话叫做 矿工
    centerqi
        39
    centerqi  
       2013-07-09 11:39:56 +08:00
    @binux 欢迎加我qq哈,qq在帖子里有。
    binux
        40
    binux  
       2013-07-09 11:49:43 +08:00
    @centerqi 上班禁止用QQ,虽然对你已经没有这个限制了
    timonwong
        41
    timonwong  
       2013-07-09 12:08:27 +08:00
    @centerqi
    BMP和PNG都还好说:
    BMP的width在0x12, height在0x16 (u32, little endian)
    PNG的width在0x10, height在0x14 (u32, big endian)

    JPEG稍微麻烦点,位置不固定,因为在magic header 0xff, 0xd8后一般都会跟个JFIF segment, 用于thumbnail,需要跳过(当然也不大,thumbnail最大也就255x255, 24bit RGB存放,无压缩),然后再读取width和height。
    est
        42
    est  
       2013-07-09 12:27:52 +08:00
    @centerqi 快速获取图片大小,HTTP HEAD一下和DL ML有嘛关系?真是自己玩了几下hadoop的锤子,啥事情都像钉子了。

    你看没看过 @phuslu 的代码?获取真实长宽也不是多复杂的事情,各种图片格式头提取也就几行代码。
    est
        43
    est  
       2013-07-09 12:36:36 +08:00
    > 你就能得到一个系数,我们每天抓取这么多图片,都是这样弄的,求这个系数很简单的,就是一个 y=ax的问题

    > 就是通过大量的数据,能训练机器,去找到这个系数。

    大哥你这个系数是矢量还是啥?

    content-length(标量) x 系数标量 = 标量,LZ想要的是 (长、宽) 这个矢量啊大哥。

    你这个系数最多能够获得图片的 像素值 (pixels),而且是 4:3 或者 16:9 常见 照片 的比例。

    对于 长微博,全景图,截屏,素材 等等图片肯定都是无效的。

    图片 ≠ 照片

    btw 我记得以前 @livid 的 footbig 就是只允许 照片,禁止 图片的。可惜这个项目终止了
    raptor
        44
    raptor  
       2013-07-09 12:59:41 +08:00
    @est 就别提footbig了……当年我还用得挺多的,传了不少片子……
    ETiV
        45
    ETiV  
       2013-07-09 13:23:14 +08:00
    图片服务器那边算出图片的宽高. 写进HTTP header. 你这边从HTTP header读.
    jasontse
        46
    jasontse  
       2013-07-09 21:29:07 +08:00 via iPad
    @centerqi 完全不可能凭经验去学习 大尺寸的纯色图片一样可以压缩到很小
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   918 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:26 · PVG 04:26 · LAX 12:26 · JFK 15:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.