我正在使用numpy的C API来编写一些用于矩阵计算的函数.今天我想将我的函数的某些部分移动到一个单独的.c文件中,并使用标题来声明它们.现在我有一个与numpy import_array函数有关的奇怪问题.我试图尽可能地简化问题.起初有工作计划:
mytest.c
#include "mytest.h"
PyObject* my_sub_function() {
npy_intp dims[2] = {2, 2};
double data[] = {0.1, 0.2, 0.3, 0.4};
PyArrayObject* matrix = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT64);
memcpy(PyArray_DATA(matrix), data, sizeof(double) * dims[0] * dims[1]);
return (PyObject*)matrix;
}
static PyObject* my_test_function(PyObject* self, PyObject* args) {
return my_sub_function();
}
static PyMethodDef methods[] = {
{"my_test_function", my_test_function, METH_VARARGS, ""},
{0, 0, 0, 0}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "mytest", 0, -1, methods
};
PyMODINIT_FUNC PyInit_mytest() {
import_array();
return PyModule_Create(&module); …Run Code Online (Sandbox Code Playgroud) 我想编写一个程序来连续捕获屏幕并对图像进行一些修改。可以在以下位置找到完整的测试程序:
https://gist.github.com/blogsh/eb4dd4b96aca468c8bfa
但是,我遇到了一些问题。我做的第一个实验是使用 Gdk 根窗口,从中创建一个 Cairo 上下文,然后使用它的目标作为另一个窗口的源,其中的内容被绘制为:
mScreenContext = Gdk::Screen::get_default()->get_root_window()->create_cairo_context()
...
context->set_source(mScreenContext->get_target(), 0, 0);
context->paint();
Run Code Online (Sandbox Code Playgroud)
这工作得很好(上面源代码中的变体 1)。它只是将整个屏幕绘制到另一个窗口中。所以我的下一步是尝试将内容保存到 Cairo ImageSurface 中以便对其进行修改:
mImageContext->set_source(mScreenContext->get_target(), 0, 0);
mImageContext->paint();
context->set_source(mImageSurface, 0, 0);
context->paint();
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,对于 Gtk 窗口的第一次绘制,屏幕被捕获并绘制。不幸的是之后没有发生任何事情,仍然显示初始屏幕。如何解释这种行为?我必须承认我对这里的底层流程了解不多,所以也许有人可以提供一些提示?
使用的第三个变体Gdk::Pixbuf产生完全相同的行为:
mScreenBuffer = Gdk::Pixbuf::create(mGdkRootWindow, 0, 0, mScreenWidth, mScreenHeight);
Gdk::Cairo::set_source_pixbuf(context, mScreenBuffer, 0, 0);
context->paint();
Run Code Online (Sandbox Code Playgroud)
最后(变体 4)我尝试X11直接使用:
Display *display = XOpenDisplay((char*)0);
XImage *image = XGetImage(display, RootWindow(display, DefaultScreen(display)), 0, 0, mScreenWidth, mScreenHeight, AllPlanes, XYPixmap);
mScreenBuffer = Gdk::Pixbuf::create_from_data((const guint8*)image->data, Gdk::COLORSPACE_RGB, 0, 8, mScreenWidth, mScreenHeight, mScreenWidth);
Gdk::Cairo::set_source_pixbuf(context, mScreenBuffer, 0, 0); …Run Code Online (Sandbox Code Playgroud)