使用 PIL.Image 和 ctypes 进行像素操作

2024-02-21

我有一个 C 函数,可以对 8 位 RGB 值的原始 2D 数组进行一些像素操作。我得到的答复是c_ubyte大批。我的代码大致如下:

from ctypes import cdll, CDLL, Structure, byref, c_utype, c_uint

# get a reference to the C shared library
cdll.loadLibrary(path_to_my_c_lib)
myclib = CDLL(path_to_my_c_lib)

# define the ctypes version of the C image that would look something like:
#     struct img {
#         unsigned char data[MAX_IMAGE_SIZE];
#         unsigned int width;
#         unsigned int height;
#     }
class Img(Structure): _fiels_ = [
    ('data', c_ubyte * MAX_IMAGE_SIZE),
    ('width', c_uint),
    ('height', c_uint),
]

# create a blank image, all pixels are black
img = Image()
img.width = WIDTH
img.height = HEIGHT

# call the C function which would look like this:
#     void my_pixel_manipulation_function(struct img *)
# and would now work its magic on the data
myclib.my_pixel_manipulation_function(byref(img))

此时我想使用 PIL 将图像写入文件。我目前使用以下代码将字节数据转换为图像数据:

from PIL import Image

s = ''.join([chr(c) for c in img.data[:(img.width*img.height*3)]])
im = Image.fromstring('RGB', (img.width, img.height), s)

# now I can...
im.save(filename)

这可行,但对我来说似乎效率很低。在 2.2GHz Core i7 上处理 592x336 图像需要 125 毫秒。当 Image 可以直接从数组中获取时,迭代整个数组并执行这种荒谬的字符串连接似乎相当愚蠢。

我尝试寻找方法来投射c_ubyte数组到字符串或者可能使用Image.frombuffer代替Image.fromstring但无法完成这项工作。


我不是 PIL 用户,但通常, frombuffer 方法是为此类工作而设计的:

你测试过Image.frombuffer吗?

http://effbot.org/imagingbook/image.htm http://effbot.org/imagingbook/image.htm

edit:

显然,有时解决方案就在我们眼皮底下:

im = Image.frombuffer('RGB', (img.width, img.height), buff, 'raw', 'RGB', 0, 1)
im.save(filename)

顺便说一下,使用简写形式frombuffer:

im = Image.frombuffer('RGB', (img.width, img.height), buff)

生成颠倒的图片。去搞清楚...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PIL.Image 和 ctypes 进行像素操作 的相关文章

  • python - 如何删除每行中的重复列表(pandas)?

    我的每一行中都包含一个列表 我想通过保留分数中的最高值来删除重复元素 这是我的数据框 df1 中的数据 pair score 0 A A 1 0000 1 A F 0 9990 2 A G 0 9985 3 A G 0 9975 4 A H
  • virtualenvwrapper 函数在 shell 脚本中不可用

    所以 我再一次制作了一个很棒的 python 程序 它让我的生活变得更加轻松 并节省了大量时间 当然 这涉及到一个 virtualenv 用mkvirtualenvvirtualenvwrapper 的功能 该项目有一个requiremen
  • 在 Python 中延迟转置列表

    所以 我有一个延迟生成的可迭代的三元组 我试图弄清楚如何将其转换为 3 个可迭代对象 分别由元组的第一个 第二个和第三个元素组成 然而 我希望这件事能懒惰地完成 所以 举例来说 我希望 1 2 3 4 5 6 7 8 9 将变成 1 4 7
  • 创建 xyz 海拔数据的曲面图

    我正在尝试用 python 创建一座山的表面图 其中我有一些 xyz 数据 最终结果应该类似于that https i stack imgur com rKQV0 png 该文件的格式如下 616000 0 90500 0 3096 712
  • 删除 tkinter 文本默认绑定

    我正在制作一个简单的 tkinter 文本编辑器 但我想要所有默认绑定文本小部件如果可能的话删除 例如当我按Ctrl i它默认插入一个制表符 我制作了一个事件绑定来打印文本框中有多少行 我将事件绑定设置为Ctrl i以及 当我运行它时 它会
  • 我可以同时打开两个 Tkinter Windows 吗?

    可以同时打开2个窗口吗 import tkinter as Tk import random import math root Tk Tk canvas Tk Canvas root background image Tk PhotoIma
  • Discord.py 斜线命令在 cogs 中不起作用

    我正在构建一个不和谐的机器人 并且想要在 cogs 内使用斜杠命令 但这些命令不显示或工作 这是代码 cog guild ids 858573429787066368 861507832934563851 class Slash comma
  • NumPy 数组与 SQLite

    我在 Python 中见过的最常见的 SQLite 接口是sqlite3 但是有什么东西可以很好地与 NumPy 数组或 rearray 配合使用吗 我的意思是 它可以识别数据类型 不需要逐行插入 并提取到 NumPy rec 数组中 有点
  • 在多核上运行 python 线程

    我知道Python 2 7不允许在不同的内核上运行多个线程 你需要使用multiprocessing模块以实现某种程度的并发性 我正在看concurrent futuresPython 3 4 中的模块 是否使用ThreadPoolExec
  • pandas 数据框的最大大小

    我正在尝试使用读取一个有点大的数据集pandas read csv or read stata功能 但我不断遇到Memory Errors 数据帧的最大大小是多少 我的理解是 只要数据适合内存 数据帧就应该没问题 这对我来说不应该是问题 还
  • Asyncio:从未检索到任务异常的怪异

    假设我有一个简单的代码 import asyncio async def exc print 1 0 loop asyncio get event loop loop create task exc try loop run forever
  • 当元组列表中相同项目的值是字符串时,对它们的值求和

    如果我有这样的元组列表 my list books 5 books 10 ink 20 paper 15 paper 20 paper 15 我怎样才能把列表变成这样 books 15 ink 20 paper 50 即添加同一项目的费用
  • 如何在 python 中使用交叉验证执行 GridSearchCV

    我正在执行超参数调整RandomForest如下使用GridSearchCV X np array df features all features y np array df gold standard labels x train x
  • matplotlib vlines 图中未应用 y 轴的最小值

    我正在 matplotlib 中绘制 vlines 图 数据集中的所有 y 值如下 gt 0 我希望 y 轴最底部的刻度能够读取0 但相反 我得到 500 这是代码 usr bin env python import numpy as np
  • 使用 Python-VLC 的 PyInstaller:无属性“media_player_new”错误

    我使用 Python VLC 创建视频播放器 并使用 PyInstaller 在 Windows 10 计算机上生成可执行文件 最初 它给了我错误 Import Error Failed to load dynlib dll libvlc
  • 使用具有可变数量索引的 numpy mggrid

    如何将 numpy mgrid 与可变数量的索引一起使用 我在 github 上找不到任何人将其与硬编码值以外的任何内容一起使用的示例 import numpy as np np mgrid 1 10 1 10 this works fin
  • 如何将 pandas DataFrame 转换为 TimeSeries?

    我正在寻找一种将 DataFrame 转换为 TimeSeries 而不拆分索引和值列的方法 有任何想法吗 谢谢 In 20 import pandas as pd In 21 import numpy as np In 22 dates
  • 在 4K 屏幕上使用 Matplotlib 和 TKAgg 或 Qt5Agg 后端

    我在 Ubuntu 16 04 上使用 Matplotlib 2 0 和 Python 3 6 来创建数据图 电脑显示器的分辨率为 4k 分辨率为 3840x2160 绘图数字看起来非常小 字体也很小 我已经尝试过TKAgg and Qt5
  • python 中的 F 字符串前缀给出语法错误[重复]

    这个问题在这里已经有答案了 我有一个名为 method 的变量 它的值是 POST 但是当我尝试运行时print f method method is used 它不断在最后一个双引号处给出语法错误 我找不到它这样做的原因 我正在使用 py
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if

随机推荐