如何用Wand从二进制字符串创建高分辨率JPEG

2024-04-26 22:32:20 发布

您现在位置:Python中文网/ 问答频道 /正文

enter image description here

我试图用imagemagick将一些PDF转换为高分辨率JPEG。我正在用python3.62-64位和wand0.4.4开发win10,64。在命令行我有:

$ /e/ImageMagick-6.9.9-Q16-HDRI/convert.exe -density 400 myfile.pdf -scale 2000x1000 test3.jpg.

这对我很有效。在

在python中:

^{pr2}$

这给了我低分辨率的jpeg图像。我怎么把它转换成我的魔杖代码来做同样的事情?在

编辑:

我意识到问题是输入的pdf必须作为二进制字符串读入Image对象,因此基于http://docs.wand-py.org/en/0.4.4/guide/read.html#read-blob我尝试了:

with open(file_path,'rb') as f:
    image_binary = f.read()

f.close()

with Image(blob=image_binary,resolution=400) as img:
    img.transform('2000x1000', '100%')
    img.make_blob('jpeg')
    img.save(filename='out.jpg')

这将读取ok中的文件,但输出被分成10个文件。为什么?我需要把这个变成1高分辨率的jpeg。在

编辑:

我需要将jpeg发送到ocrapi,所以我想知道是否可以将输出写入类似文件的对象。看着https://www.imagemagick.org/api/magick-image.php#MagickWriteImageFile,我试着:

emptyFile =  Image(width=1500, height=2000)

with Image(filename=file_path, resolution=400) as image:

    library.MagickResetIterator(image.wand)
    # Call C-API append method.
    resource_pointer = library.MagickAppendImages(image.wand,
                                                  True)

    library.MagickWriteImagesFile(resource_pointer,emptyFile)

这样可以得到:

 File "E:/ENVS/r3/pdfminer.six/ocr_space.py", line 113, in <module>
test_file = ocr_stream(filename='test4.jpg')
 File "E:/ENVS/r3/pdfminer.six/ocr_space.py", line 96, in ocr_stream
library.MagickWriteImagesFile(resource_pointer,emptyFile)
ctypes.ArgumentError: argument 2: <class 'TypeError'>: wrong type

我怎样才能让它工作?在


Tags: pyimageimgreadaswithlibrarywand
2条回答

比如说:

ok = Image(filename=file_path, resolution=400)
with ok.transform('2000x1000', '100%') as image:
   image.compression_quality = 100
   image.save()

或者:

^{pr2}$

相关:

Why? I need to get this into 1 high res jpeg.

PDF包含ImageMagick在“堆栈”中考虑单个图像的页面。库提供一个wand.image.Image.sequance来处理每个页面。在

但是,要将所有图像附加到单个JPEG中。您可以迭代每个页面并将它们缝合在一起,或者调用C-API的方法MagickAppendImages。在

from wand.image import Image
from wand.api import library
import ctypes

# Map C-API not provided by wand library.
library.MagickAppendImages.argtypes = [ctypes.c_void_p, ctypes.c_int]
library.MagickAppendImages.restype = ctypes.c_void_p

with Image(filename="path_to_document.pdf", resolution=400) as image:
    # Do all your preprocessing first
    # Ether word directly on the wand instance, or iterate over each page.
    # ...
    # To write all "pages" into a single image.
    # Reset the stack iterator.
    library.MagickResetIterator(image.wand)                    
    # Call C-API Append method.
    resource_pointer = library.MagickAppendImages(image.wand,
                                                  True)        
    # Write C resource directly to disk.
    library.MagickWriteImages(resource_pointer,                
                              "output.jpeg".encode("ASCII"),
                              False)

更新:

I need to send the jpeg to an OCR api ...

假设您使用OpenCV的pythonapi,那么您只需要遍历每个页面,并通过numpy缓冲区将图像文件数据传递到OCR。在

^{pr2}$

so I was wondering if I could write the output to a file like object

不要假设来自不同库的python“image”对象(或下划线C结构)是可比较的。

在不了解OCR api的情况下,我无法帮助您跳过部分,但我可以建议以下其中一个。。。在

  • 使用临时中间文件。(I/O速度较慢,但更易于学习/开发/调试)

    with Image(filename=INPUT_PATH) as img:
        # work
        img.save(filename=OUTPUT_PATH)
    # OCR work on OUTPUT_PATH
    
  • 如果OCR API支持,请使用文件描述符。(同上)

    with open(INPUT_PATH, 'rb') as fd:
        with Image(file=fd) as img:
            # work
            # OCR work ???
    
  • 使用斑点。(更快的I/O,但需要更多内存)

    buffer = None
    with Image(filename=INPUT_PATH) as img:
        # work
        buffer = img.make_blob(FORMAT)
    if buffer:
        # OCR work ???
    

更多更新

把所有的评论放在一起,一个解决方案可能是。。。在

from wand.image import Image
from wand.api import library
import ctypes
import requests

# Map C-API not provided by wand library.
library.MagickAppendImages.argtypes = [ctypes.c_void_p, ctypes.c_int]
library.MagickAppendImages.restype = ctypes.c_void_p

with Image(filename='path_to_document.pdf', resolution=400) as image:
    # ... Do pre-processing ...
    # Reset the stack iterator.
    library.MagickResetIterator(image.wand)
    # Call C-API Append method.
    resource_pointer = library.MagickAppendImages(image.wand, True)
    # Convert to JPEG.
    library.MagickSetImageFormat(resource_pointer, b'JPEG')
    # Create size sentinel.
    length = ctypes.c_size_t()
    # Write image blob to memory.
    image_data_pointer = library.MagickGetImagesBlob(resource_pointer,
                                                     ctypes.byref(length))
    # Ensure success
    if image_data_pointer and length.value:
        # Create buffer from memory address
        payload = ctypes.string_at(image_data_pointer, length.value)
        # Define local filename.
        payload_filename = 'my_hires_image.jpg'
        # Post payload as multipart encoded image file with filename.
        requests.post(THE_URL, files={'file': (payload_filename, payload)})

相关问题 更多 >