【问题标题】:How to save this file?如何保存这个文件?
【发布时间】:2017-11-12 12:30:56
【问题描述】:

所以我得到了让用户输入图像的 HTML 代码:

<label class="tab-item"> Browse
    <span class="icon icon-more"></span>
    <input type="file" accept="image/*"  name="image_save" value="image_save" onchange="updatePhoto(event);"></input>
</label>

#some more code

<form action="../api/save" method="post">
    <button type="submit" name="image_save" class="btn btn-positive btn-block" href="../api.put" value="image_save">
        Test Save
    </button>
</form>

在一个 Python 文件中,我有:

@cherrypy.expose
def save(self, image_save=None):
    f = open(image_save)
    f.save("../photos/" + "test" + ".png", "PNG")
    return "Image saved"

但是我得到了错误

IOError: [Errno 2] No such file or directory: u'image_save'"

你们将如何保存通过 HTML 代码给出的图像?什么类型的数据作为方法参数给出?

【问题讨论】:

  • 您收到错误是因为您的 image_save 参数设置为 None;你怎么能打开None 类型的对象? open() 需要提供路径(以及我相信的模式)。建议您也使用 with open() 进行文件 I/O,因为它会在所有嵌套代码完成后关闭。
  • @pstatix 据我所知,这是变量的初始值。在其他情况下,例如文本输入,它可以很好地与 None 配合使用。我只想知道如何在这种情况下进行图像保存,因为我在其他任何地方都找不到它。我什至不知道什么类型的数据被发送到变量。我可以以任何方式或类似方式使用 PIL 吗?那是我的问题。
  • 如果您检查了错误日志/控制台,或者甚至测试打印出 image_save 的值,您会发现它没有被填充。我也没有得到接受参数。您不应该将其限制为 png/jpg/gif 吗? (然后检查 mime 类型以确保..)
  • @RachelGallen 那你会怎么做呢?我愿意接受建议。
  • @PioAvenger 是的,您可以将其作为None 类型启动,但如果您想使用open(),则必须在某个时候提供一个值;只看逻辑。如果我做了open(None)...它没有什么可以打开的!

标签: python html image cherrypy


【解决方案1】:

this site 有一个最小的例子,它给出了这个 python 文件上传的例子:

#!/usr/local/bin/python
"""This demonstrates a minimal http upload cgi.
This allows a user to upload up to three files at once.
It is trivial to change the number of files uploaded.

This script has security risks. A user could attempt to fill
a disk partition with endless uploads. 
If you have a system open to the public you would obviously want
to limit the size and number of files written to the disk.
"""
import cgi
import cgitb; cgitb.enable()
import os, sys
try: # Windows needs stdio set for binary mode.
    import msvcrt
    msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
    msvcrt.setmode (1, os.O_BINARY) # stdout = 1
except ImportError:
    pass

UPLOAD_DIR = "/tmp"

HTML_TEMPLATE = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head><body><h1>File Upload</h1>
<form action="%(SCRIPT_NAME)s" method="POST" enctype="multipart/form-data">
File name: <input name="file_1" type="file"><br>
File name: <input name="file_2" type="file"><br>
File name: <input name="file_3" type="file"><br>
<input name="submit" type="submit">
</form>
</body>
</html>"""

def print_html_form ():
    """This prints out the html form. Note that the action is set to
      the name of the script which makes this is a self-posting form.
      In other words, this cgi both displays a form and processes it.
    """
    print "content-type: text/html\n"
    print HTML_TEMPLATE % {'SCRIPT_NAME':os.environ['SCRIPT_NAME']}

def save_uploaded_file (form_field, upload_dir):
    """This saves a file uploaded by an HTML form.
       The form_field is the name of the file input field from the form.
       For example, the following form_field would be "file_1":
           <input name="file_1" type="file">
       The upload_dir is the directory where the file will be written.
       If no file was uploaded or if the field does not exist then
       this does nothing.
    """
    form = cgi.FieldStorage()
    if not form.has_key(form_field): return
    fileitem = form[form_field]
    if not fileitem.file: return
    fout = file (os.path.join(upload_dir, fileitem.filename), 'wb')
    while 1:
        chunk = fileitem.file.read(100000)
        if not chunk: break
        fout.write (chunk)
    fout.close()

save_uploaded_file ("file_1", UPLOAD_DIR)
save_uploaded_file ("file_2", UPLOAD_DIR)
save_uploaded_file ("file_3", UPLOAD_DIR)

print_html_form ()

其他建议

我建议您将输入类型更改为

 <input type="file" name="image_save" accept="image/x-png,image/gif,image/jpeg" />

而不是 image/* 以限制为 png/jpg/gif。可以使用php 检查 MIME 类型,我还建议您添加 upload_max_filesize(也在 php 中)

最后将fout这一行改为

 fout = open(pathname, 'wb')

虽然file() 构造函数是open() 的别名,但为了未来和向后兼容,open() 仍然是首选。

【讨论】:

  • 谢谢,这是有道理的。我现在就试试^^
  • @PioAvenger 太棒了,祝你好运。任何其他问题,再次发布(但无论如何网站上可能还有其他示例..)..很高兴帮助:)
猜你喜欢
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
相关资源
最近更新 更多