Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Tips / File Uploading and Handling

File Uploading and Handling

Image 和 File 檔案處理的相關功能,包括上傳、下載、線上顯示等。

kernel 這個字在 Image Processing 領域代表一種濾鏡,基本是一個小矩陣,正中間代表「新影像中的某一個像素」,其周邊的值代表權重。

用 Python 提取 PDF 文字內容

除了用 Image 外,也可以使用 File 來上傳圖檔,主要差別在於 File 不會主動產生縮圖。利用 collective.pdfpeek 可以為上傳的 PDF 建立縮圖。

轉 PDF 用 jsPdf 應該夠,若要全圖pdf可用html2canvas轉圖再轉pdf, 若要有由docx或xlsx或odt等轉pdf,由後端做比較容易。用html2canvas轉出canvas再轉點陣圖即可,記得html2canvas要設定scale放大(2~3倍),也就是類似anti-aliasing,否則解析度等同於截圖,轉出pdf會很糊。 https://www.youtube.com/watch?v=vfuAVi48S6w 這個似乎不用 canvas 通常基本html沒問題,若上面dom比較複雜或有繪圖套件所生成的svg,通常會爆版,都轉成圖再轉出pdf會比較簡單。

上傳 _ 開頭的檔名會產生錯誤 Fetch File (Image, PDF) from URL: izug.seantis.dir.events/import.py

Image Attribute for EEA FacetedNavigation Thumbnail: Behavior + IObjectModifiedEvent possible example: eea.alchemy

collective.upload

read metadata form IPTC IIM properties if present collective.documentfile jQuery File Upload library

wildcard.foldercontents (Plone 4.3.4 pins) 支援批次上傳檔案的功能,在 Plone 5 則內建納入這個模組,名稱定為 plone.foldercontents,既有的類似模組也很多。

Archetypes 的 ATImage 和 ATFile 都繼承自 ATBlob,透過 ImageMixin 達到向後相容的效果。OFS 圖檔昇級轉換到 Dexterity 的討論,用 NamedBlobFiles 取代 OFSImage 的範例: collective.pdfpeek

使用 plone.api + NamedBlobFile

不同於一般方式,要在 form 裡建立一個 FileUpload 的物件欄位,想要取得物件路徑,可以使用 REQUEST.yourfile.filename 也就是 filename 屬性值來取得物件路徑。

NamedFile 不會把檔案存到 var/blobstorage 裡,NamedBlobFile 才會,除此之外,兩者功能相同。

參考 plone.app.contenttypes/tests/test_image.py 和 content.py 範例:

from plone.namedfile.file import NamedBlobImage
filename = u'myfile.png'

obj = createContentInContainer(folder, 'Image',
        image=NamedBlobImage(data=open(filename, 'r').read(), filename=filename))
<div tal:define="picture nocall:context/picture"
     tal:condition="nocall:picture">
  <img tal:attribute="src string:${context/absolute_url}/@@download/picture/${picture/filename};
                      height picture/_height | nothing;
                      width picture/_width | nothing;" />
</div>

另一個範例

<div tal:define="images view/images"
     tal:condition="images">
   <span tal:repeat="obj images">
   <img src="" alt=""
    tal:attributes="src string:${obj/getURL}/image/preview" />
   </span>
</div>

/portal_skins/archetypes/at_download: AttributeError: 'RequestContainer' object has no attribute 'getWrappedField' BlobWrapper vs File Instance: uwosh.pfg.d2c at_download stored as blobs make view override optional

plone.app.imagecropping: Generate cropped scales instead of uncropped scales after storage._cleanup() has run 版本議題造成 ImportError 錯誤 JPEG CMYK 模式在新版能處理得更好

view = self.img.restrictedTraverse('@@crop-image')
traverse = self.portal.REQUEST.traverseName
scales = traverse(self.img, '@@images')
uncropped_thumb = scales.scale('image', 'thumb')

上傳限制

Web Server 預設會有上傳的大小限制,以 Nginx 為例,在 /etc/nginx/proxy.conf 可找到 client_max_body_size    10m; 設定值。

Plone5 + HTTPs 造成檔案上傳 500Kb 限制 Dexterity Validator for Uploaded Files

# -*- coding: utf-8 -*-
from plone.namedfile.interfaces import INamedBlobImageField
# from plone.app.contenttypes.interfaces import IImage
from zope.interface import Invalid
from z3c.form import validator


# 1 MB size limit
MAXSIZE = 1024 * 1024


class ImageFileSizeValidator(validator.FileUploadValidator):

    def validate(self, value):
        super(ImageFileSizeValidator, self).validate(value)

        if value.getSize() > MAXSIZE:
            raise Invalid("Image is too large (to many bytes)")


validator.WidgetValidatorDiscriminators(ImageFileSizeValidator,
#                                        context=IImage,
                                        field=INamedBlobImageField)
<adapter factory=".validators.ImageFileSizeValidator" />

限制上傳的檔案類型 限制圖檔類型 上傳圖檔時限制 PDF 格式: Archetypes IObjectPostValidation Event Subscriber to Limit File Types

限制上傳圖檔的尺寸 IWebDAVObjectInitializedEvent FileSize Validator for Dexterity

zope.size

File Image In Batch Via Zip: atreal.massloader

Image Contents Validation Methods among Archetypes Versions

Image Getter: collective.loremipsum

Using is_zipfile on ZPublisher.HTTPRequest.FileUpload

取消下載 Disable Download File

限制成員上傳的容量 限制上傳容量 Products.feedfeeder 範例 判斷上傳檔案是否存在

<span tal:condition="context/attachment/get_size">ATTACHMENT</span>

collective.quickupload wildcard.media list index out of range wildcard.media 相容性

Download

Archetype File with restrictedtraverse

eea.pdf: 透過 PDF 下載內容 eea.converter 利用 urllib.urlretrieve('http://site.net/shared/'+filename, filename) 可以批次下載圖檔

Products.ATContentTypes/lib/imagetransform.py getImageAsFile()

    image = self.getImageAsFile()
    image2 = StringIO()

    if image is not None:
        img = PIL.Image.open(image)
        del image
        fmt = img.format
        img = img.transpose(method)
        img.save(image2, fmt, quality=zconf.pil_config.quality)

批次下載圖檔不同尺寸

File Data from Shell

obj = app.restrictedTraverse(„path/to/object)
data = str(obj,file.data)

線上顯示

Google Docs Microsoft Office Auto Rotate Dexterity Images Based on EXIF Information

Embedded PDF in File View

<object tal:condition="python:content_type.endswith('pdf')"
 class="viewembededfile" type="application/pdf"
 data="" tal:attributes="data location">
<a href="" tal:attributes="href location">
Click to Download
</a>
<embed src="" class="viewembededfile"
 type="application/pdf" tal:attributes="src location">
</embed>
</object>

collective.documentviewer: PDF 和 Office 檔案都能線上顯示,進行文字辨識。LibreOffice 4.1 與 docsplit 版本問題Archetypes 與 Dexterity 參照問題

wc.pageturner: 搭配 Flex Paper 和 SWFtool 進行線上顯示。

collective.pdfjs: 搭配 Mozilla JavaScript PDF Reader 或 Native Reader Plugin 進行線上顯示。

Embedded PDF in File View: 搭配 HTTP Content Type 和 Native Reader Plugin 進行線上顯示。

z3c.rml: ReportLab's RML PDF generation XML format

IE 瀏覽器顯示 Flash z3c.form with NamedImageFieldWidget

在 Portlet 顯示圖檔 在 Related Item 顯示圖檔

resolveuid images jQuery LightBox PrettyPhoto

MediaElement.js: collective.mediaelementjs

MP3 Cut

CSS Paged Media PDF 中文字型可能要搭配新版 freetype 才行

辨識 OCR H264: wildcard.media OSX Safari avconv params

依角色權限顯示

import requests
url = "https://"
payload = "token="
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.post(url, headers=headers, data=payload)

tarfile.open(io.BytesIO(response.content), 'r:bz2') https://docs.python.org/3/library/tarfile.html x-www-form-urlencoded 不用指定 header,直接 requests.post(url, data={'token': 'TOKEN'}) 就可以了 上傳 Zip 檔案可以建立內容 collective.documentfusion: fusion of the variables and bookmarks of a file field, LibreOffice as a service

TinyMCE Batch Uploading PDF Image Caption: html-to-captioned

PNG 支援背景透明功能: z3c.rml transparent

react-pdf

存取檔案系統

Reflecto Upload Large Files

>>> fldr['2011']['09']['China-and-the-West.pdf'].file
<plone.namedfile.file.NamedBlobFile object at 0x7f81a3c45398>
>>> dir(fldr['2011']['09']['China-and-the-West.pdf'].file)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getstate__',
'__hash__', '__implemented__', '__init__', '__module__', '__new__', '__providedBy__', '__provides__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_data', '_getData', '_p_activate', '_p_changed', '_p_deactivate',
'_p_delattr', '_p_estimated_size', '_p_getattr', '_p_invalidate',
'_p_jar', '_p_mtime', '_p_oid', '_p_serial', '_p_setattr', '_p_state',
'_setData', 'data', 'filename', 'getSize', 'open', 'openDetached', 'size']
>>> fldr['2011']['09']['China-and-the-West.pdf'].file.filename
u'China-and-the-West.pdf'
>>> fldr['2011']['09']['China-and-the-West.pdf'].file.__dict__
{'_blob': <zodb.blob.blob object at 0x7f81a3c45488>,
 'contentType': 'application/pdf', 'filename': u'China-and-the-West.pdf', 'size': 223747}

Bad Images: plone.app.imagecropping

>>> from zope.annotation import IAnnotations
>>> from plone.app.imagecropping import PAI_STORAGE_KEY
>>> all_images = app.Plone.portal_catalog(portal_type='Image')
>>> bad_images = [x.getObject() for x in all_images if PAI_STORAGE_KEY in IAnnotations(x.getObject())]
>>> dont_care = [(IAnnotations(x).pop(PAI_STORAGE_KEY), x.setModificationDate()) for x in bad_images]
>>> import transaction
>>> transaction.commit()

批次下載圖檔

imgs = {'folder1': ['img1.jpg', 'img2.png'], 'folder2': ['myimg.png']}
for i in imgs.keys():
    os.chdir('/tmp/download')
    os.mkdir(i)
    os.chdir('/tmp/download/'+i)
    for j in imgs[i]:
        urllib.urlretrieve('http://site.com/folder/'+i+'/'+j, j)

django-filer

IIIF

http://iiif.io/api/presentation/2.0/
http://dms-data.stanford.edu/data/manifests/Walters/qm670kv1873/manifest.json
http://iiif.io/api/presentation/2/context.json

http://github.com/IIIF/showcase.iiif.io
http://github.com/IIIF/mirador
http://gist.github.com/sdellis/5d3b0da75c4b301ecbeb
http://iiif.io/api/image/2.0/
http://iiif.io/api/presentation/2.0/example/fixtures/collection.json
http://iiif.io/api/presentation/2.0/example/fixtures/1/manifest.json

Windows File

multi-process share same log file (C++ C#)