Windows、Linux、macOS 用の軽量 C カメラ SDK が完成したので、これを他の高級プログラミング言語に統合できます。この記事では、C カメラ ライブラリに基づいて Python カメラ SDK を構築し、それを Dynamsoft Barcode Reader SDK でマルチバーコード スキャンに使用する方法を検討します。
CPython 拡張機能は、共有ライブラリ (Windows の DLL、Linux の .so、macOS の .dylib など) です。実行時に Python インタープリターにロードし、その機能を拡張するために使用できます。 Lite カメラ CPython 拡張プロジェクトの構造は次のとおりです:
python-lite-camera │ │── include │ ├── Camera.h │ ├── CameraPreview.h │ ├── stb_image_write.h │── lib │ ├── linux │ │ ├── liblitecam.so │ ├── macos │ │ ├── liblitecam.dylib │ ├── windows │ │ ├── litecam.dll │ │ ├── litecam.lib ├── src │ ├── litecam.cpp │ ├── pycamera.h │ ├── pywindow.h │── litecam │ ├── __init__.py │── setup.py │── MANIFEST.in │── README.md
説明:
次のコンテンツを setup.py に追加します:
from setuptools.command import build_ext from setuptools import setup, Extension import sys import os import io from setuptools.command.install import install import shutil from pathlib import Path lib_dir = '' sources = [ "src/litecam.cpp", ] include_dirs = [os.path.join(os.path.dirname(__file__), "include")] libraries = ['litecam'] extra_compile_args = [] if sys.platform == "linux" or sys.platform == "linux2": lib_dir = 'lib/linux' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath=$ORIGIN"] elif sys.platform == "darwin": lib_dir = 'lib/macos' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath,@loader_path"] elif sys.platform == "win32": lib_dir = 'lib/windows' extra_link_args = [] else: raise RuntimeError("Unsupported platform") long_description = io.open("README.md", encoding="utf-8").read() module_litecam = Extension( "litecam", sources=sources, include_dirs=include_dirs, library_dirs=[lib_dir], libraries=libraries, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) def copyfiles(src, dst): if os.path.isdir(src): filelist = os.listdir(src) for file in filelist: libpath = os.path.join(src, file) shutil.copy2(libpath, dst) else: shutil.copy2(src, dst) class CustomBuildExt(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dst = os.path.join(self.build_lib, "litecam") copyfiles(lib_dir, dst) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dst) os.remove(filePath) class CustomBuildExtDev(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dev_folder = os.path.join(Path(__file__).parent, 'litecam') copyfiles(lib_dir, dev_folder) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dev_folder) class CustomInstall(install): def run(self): install.run(self) setup(name='lite-camera', version='2.0.1', description='LiteCam is a lightweight, cross-platform library for capturing RGB frames from cameras and displaying them. Designed with simplicity and ease of integration in mind, LiteCam supports Windows, Linux and macOS platforms.', long_description=long_description, long_description_content_type="text/markdown", author='yushulx', url='https://github.com/yushulx/python-lite-camera', license='MIT', packages=['litecam'], ext_modules=[module_litecam], classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: C++", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering", "Topic :: Software Development", ], cmdclass={ 'install': CustomInstall, 'build_ext': CustomBuildExt, 'develop': CustomBuildExtDev}, )
説明:
pycamera.h ファイルはカメラからフレームをキャプチャするための PyCamera Python クラスを定義し、pywindow.h ファイルはウィンドウにフレームを表示するための PyWindow Python クラスを定義します。 litecam.cpp ファイルは Python 拡張機能のエントリ ポイントとして機能し、いくつかのグローバル メソッドが定義され、PyCamera クラスと PyWindow クラスが登録されます。
python-lite-camera │ │── include │ ├── Camera.h │ ├── CameraPreview.h │ ├── stb_image_write.h │── lib │ ├── linux │ │ ├── liblitecam.so │ ├── macos │ │ ├── liblitecam.dylib │ ├── windows │ │ ├── litecam.dll │ │ ├── litecam.lib ├── src │ ├── litecam.cpp │ ├── pycamera.h │ ├── pywindow.h │── litecam │ ├── __init__.py │── setup.py │── MANIFEST.in │── README.md
from setuptools.command import build_ext from setuptools import setup, Extension import sys import os import io from setuptools.command.install import install import shutil from pathlib import Path lib_dir = '' sources = [ "src/litecam.cpp", ] include_dirs = [os.path.join(os.path.dirname(__file__), "include")] libraries = ['litecam'] extra_compile_args = [] if sys.platform == "linux" or sys.platform == "linux2": lib_dir = 'lib/linux' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath=$ORIGIN"] elif sys.platform == "darwin": lib_dir = 'lib/macos' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath,@loader_path"] elif sys.platform == "win32": lib_dir = 'lib/windows' extra_link_args = [] else: raise RuntimeError("Unsupported platform") long_description = io.open("README.md", encoding="utf-8").read() module_litecam = Extension( "litecam", sources=sources, include_dirs=include_dirs, library_dirs=[lib_dir], libraries=libraries, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) def copyfiles(src, dst): if os.path.isdir(src): filelist = os.listdir(src) for file in filelist: libpath = os.path.join(src, file) shutil.copy2(libpath, dst) else: shutil.copy2(src, dst) class CustomBuildExt(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dst = os.path.join(self.build_lib, "litecam") copyfiles(lib_dir, dst) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dst) os.remove(filePath) class CustomBuildExtDev(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dev_folder = os.path.join(Path(__file__).parent, 'litecam') copyfiles(lib_dir, dev_folder) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dev_folder) class CustomInstall(install): def run(self): install.run(self) setup(name='lite-camera', version='2.0.1', description='LiteCam is a lightweight, cross-platform library for capturing RGB frames from cameras and displaying them. Designed with simplicity and ease of integration in mind, LiteCam supports Windows, Linux and macOS platforms.', long_description=long_description, long_description_content_type="text/markdown", author='yushulx', url='https://github.com/yushulx/python-lite-camera', license='MIT', packages=['litecam'], ext_modules=[module_litecam], classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: C++", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering", "Topic :: Software Development", ], cmdclass={ 'install': CustomInstall, 'build_ext': CustomBuildExt, 'develop': CustomBuildExtDev}, )
PyCamera 構造体は、C Camera オブジェクトをラップする Python オブジェクトを表します。ハンドラーは、Camera クラスのインスタンスへのポインターです。
PyCamera_dealloc
#include <Python.h> #include <structmember.h> #include "Camera.h"
Camera オブジェクトの割り当てを解除し、関連付けられたメモリを解放します。
PyCamera_new
typedef struct { PyObject_HEAD Camera *handler; } PyCamera;
PyCamera の新しいインスタンスを作成します。 Python オブジェクトにメモリを割り当て、新しい Camera オブジェクトを作成し、それを self->handler に割り当てます。
開く
static int PyCamera_clear(PyCamera *self) { if (self->handler) { delete self->handler; } return 0; } static void PyCamera_dealloc(PyCamera *self) { PyCamera_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); }
指定されたインデックスでカメラを開きます。
メディアタイプのリスト
static PyObject *PyCamera_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyCamera *self; self = (PyCamera *)type->tp_alloc(type, 0); if (self != NULL) { self->handler = new Camera(); } return (PyObject *)self; }
サポートされているメディア タイプのリストを返します。 Windows の場合、ワイド文字列を Python Unicode オブジェクトに変換します。
リリース
static PyObject *open(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int index = 0; if (!PyArg_ParseTuple(args, "i", &index)) { return NULL; } bool ret = self->handler->Open(index); return Py_BuildValue("i", ret); }
カメラを解放します。
setResolution
static PyObject *listMediaTypes(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; std::vector<MediaTypeInfo> mediaTypes = self->handler->ListSupportedMediaTypes(); PyObject *pyList = PyList_New(0); for (size_t i = 0; i < mediaTypes.size(); i++) { MediaTypeInfo &mediaType = mediaTypes[i]; #ifdef _WIN32 PyObject *subtypeName = PyUnicode_FromWideChar(mediaType.subtypeName, wcslen(mediaType.subtypeName)); PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:O}", "width", mediaType.width, "height", mediaType.height, "subtypeName", subtypeName); if (subtypeName != NULL) { Py_DECREF(subtypeName); } #else PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:s}", "width", mediaType.width, "height", mediaType.height, "subtypeName", mediaType.subtypeName); #endif PyList_Append(pyList, pyMediaType); } return pyList; }
カメラの解像度を設定します。
キャプチャフレーム
static PyObject *release(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; self->handler->Release(); Py_RETURN_NONE; }
カメラからフレームをキャプチャし、RGB データを Python バイト配列として返します。
getWidth と getHeight
static PyObject *setResolution(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int width = 0, height = 0; if (!PyArg_ParseTuple(args, "ii", &width, &height)) { return NULL; } int ret = self->handler->SetResolution(width, height); return Py_BuildValue("i", ret); }
キャプチャされたフレームの幅と高さを返します。
static PyObject *captureFrame(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; FrameData frame = self->handler->CaptureFrame(); if (frame.rgbData) { PyObject *rgbData = PyByteArray_FromStringAndSize((const char *)frame.rgbData, frame.size); PyObject *pyFrame = Py_BuildValue("iiiO", frame.width, frame.height, frame.size, rgbData); ReleaseFrame(frame); return pyFrame; } else { Py_RETURN_NONE; } }
PyCamera Python オブジェクトで使用できるメソッドを定義します。これらのメソッドは、上で定義した対応する C 関数に関連付けられています。
static PyObject *getWidth(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int width = self->handler->frameWidth; return Py_BuildValue("i", width); } static PyObject *getHeight(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int height = self->handler->frameHeight; return Py_BuildValue("i", height); }
メソッド、メモリ割り当て、割り当て解除、その他の動作を含む PyCamera タイプを定義します。
static PyMethodDef instance_methods[] = { {"open", open, METH_VARARGS, NULL}, {"listMediaTypes", listMediaTypes, METH_VARARGS, NULL}, {"release", release, METH_VARARGS, NULL}, {"setResolution", setResolution, METH_VARARGS, NULL}, {"captureFrame", captureFrame, METH_VARARGS, NULL}, {"getWidth", getWidth, METH_VARARGS, NULL}, {"getHeight", getHeight, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL}};
static PyTypeObject PyCameraType = { PyVarObject_HEAD_INIT(NULL, 0) "litecam.PyCamera", /* tp_name */ sizeof(PyCamera), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyCamera_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ "PyCamera", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ instance_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ PyCamera_new, /* tp_new */ };
C CameraWindow オブジェクトをラップする PyWindow 構造体を定義します。ハンドラー メンバーは、CameraWindow のインスタンスを指します。
PyWindow_dealloc
#include <Python.h> #include <structmember.h> #include "CameraPreview.h"
CameraWindow オブジェクトの割り当てを解除し、メモリを解放します。
PyWindow_new
typedef struct { PyObject_HEAD CameraWindow *handler; } PyWindow;
PyWindow の新しいインスタンスを作成します。 Python オブジェクトにメモリを割り当て、新しい CameraWindow オブジェクトを作成し、それを self->handler に割り当てます。
waitKey
python-lite-camera │ │── include │ ├── Camera.h │ ├── CameraPreview.h │ ├── stb_image_write.h │── lib │ ├── linux │ │ ├── liblitecam.so │ ├── macos │ │ ├── liblitecam.dylib │ ├── windows │ │ ├── litecam.dll │ │ ├── litecam.lib ├── src │ ├── litecam.cpp │ ├── pycamera.h │ ├── pywindow.h │── litecam │ ├── __init__.py │── setup.py │── MANIFEST.in │── README.md
キー押下イベントを待機し、キーが指定された文字と一致する場合は False を返します。 False は、アプリケーションを終了する必要があることを意味します。
showFrame
from setuptools.command import build_ext from setuptools import setup, Extension import sys import os import io from setuptools.command.install import install import shutil from pathlib import Path lib_dir = '' sources = [ "src/litecam.cpp", ] include_dirs = [os.path.join(os.path.dirname(__file__), "include")] libraries = ['litecam'] extra_compile_args = [] if sys.platform == "linux" or sys.platform == "linux2": lib_dir = 'lib/linux' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath=$ORIGIN"] elif sys.platform == "darwin": lib_dir = 'lib/macos' extra_compile_args = ['-std=c++11'] extra_link_args = ["-Wl,-rpath,@loader_path"] elif sys.platform == "win32": lib_dir = 'lib/windows' extra_link_args = [] else: raise RuntimeError("Unsupported platform") long_description = io.open("README.md", encoding="utf-8").read() module_litecam = Extension( "litecam", sources=sources, include_dirs=include_dirs, library_dirs=[lib_dir], libraries=libraries, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) def copyfiles(src, dst): if os.path.isdir(src): filelist = os.listdir(src) for file in filelist: libpath = os.path.join(src, file) shutil.copy2(libpath, dst) else: shutil.copy2(src, dst) class CustomBuildExt(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dst = os.path.join(self.build_lib, "litecam") copyfiles(lib_dir, dst) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dst) os.remove(filePath) class CustomBuildExtDev(build_ext.build_ext): def run(self): build_ext.build_ext.run(self) dev_folder = os.path.join(Path(__file__).parent, 'litecam') copyfiles(lib_dir, dev_folder) filelist = os.listdir(self.build_lib) for file in filelist: filePath = os.path.join(self.build_lib, file) if not os.path.isdir(file): copyfiles(filePath, dev_folder) class CustomInstall(install): def run(self): install.run(self) setup(name='lite-camera', version='2.0.1', description='LiteCam is a lightweight, cross-platform library for capturing RGB frames from cameras and displaying them. Designed with simplicity and ease of integration in mind, LiteCam supports Windows, Linux and macOS platforms.', long_description=long_description, long_description_content_type="text/markdown", author='yushulx', url='https://github.com/yushulx/python-lite-camera', license='MIT', packages=['litecam'], ext_modules=[module_litecam], classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: C++", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering", "Topic :: Software Development", ], cmdclass={ 'install': CustomInstall, 'build_ext': CustomBuildExt, 'develop': CustomBuildExtDev}, )
ウィンドウ内にフレームを表示します。
輪郭を描く
#include <Python.h> #include <structmember.h> #include "Camera.h"
フレーム上に輪郭 (一連の点) を描画します。
描画テキスト
typedef struct { PyObject_HEAD Camera *handler; } PyCamera;
フレーム上にテキストを描画します。
static int PyCamera_clear(PyCamera *self) { if (self->handler) { delete self->handler; } return 0; } static void PyCamera_dealloc(PyCamera *self) { PyCamera_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); }
PyWindow Python オブジェクトで使用できるメソッドを定義します。
static PyObject *PyCamera_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyCamera *self; self = (PyCamera *)type->tp_alloc(type, 0); if (self != NULL) { self->handler = new Camera(); } return (PyObject *)self; }
メソッド、メモリ割り当て、割り当て解除、その他の動作を含む PyWindow 型を定義します。
static PyObject *open(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int index = 0; if (!PyArg_ParseTuple(args, "i", &index)) { return NULL; } bool ret = self->handler->Open(index); return Py_BuildValue("i", ret); }
説明:
開発モード
static PyObject *listMediaTypes(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; std::vector<MediaTypeInfo> mediaTypes = self->handler->ListSupportedMediaTypes(); PyObject *pyList = PyList_New(0); for (size_t i = 0; i < mediaTypes.size(); i++) { MediaTypeInfo &mediaType = mediaTypes[i]; #ifdef _WIN32 PyObject *subtypeName = PyUnicode_FromWideChar(mediaType.subtypeName, wcslen(mediaType.subtypeName)); PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:O}", "width", mediaType.width, "height", mediaType.height, "subtypeName", subtypeName); if (subtypeName != NULL) { Py_DECREF(subtypeName); } #else PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:s}", "width", mediaType.width, "height", mediaType.height, "subtypeName", mediaType.subtypeName); #endif PyList_Append(pyList, pyMediaType); } return pyList; }
ホイールパッケージ
static PyObject *release(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; self->handler->Release(); Py_RETURN_NONE; }
ソース配布
static PyObject *setResolution(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int width = 0, height = 0; if (!PyArg_ParseTuple(args, "ii", &width, &height)) { return NULL; } int ret = self->handler->SetResolution(width, height); return Py_BuildValue("i", ret); }
Python カメラ SDK と Dynamsoft Barcode Reader SDK をインストールします:
static PyObject *captureFrame(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; FrameData frame = self->handler->CaptureFrame(); if (frame.rgbData) { PyObject *rgbData = PyByteArray_FromStringAndSize((const char *)frame.rgbData, frame.size); PyObject *pyFrame = Py_BuildValue("iiiO", frame.width, frame.height, frame.size, rgbData); ReleaseFrame(frame); return pyFrame; } else { Py_RETURN_NONE; } }
Dynamsoft Barcode Reader の 30 日間の無料試用ライセンスを取得します。
マルチバーコードスキャン用の Python スクリプトを作成します:
static PyObject *getWidth(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int width = self->handler->frameWidth; return Py_BuildValue("i", width); } static PyObject *getHeight(PyObject *obj, PyObject *args) { PyCamera *self = (PyCamera *)obj; int height = self->handler->frameHeight; return Py_BuildValue("i", height); }
LICENSE-KEY を Dynamsoft Barcode Reader のライセンス キーに置き換えます。
スクリプトを実行します:
static PyMethodDef instance_methods[] = { {"open", open, METH_VARARGS, NULL}, {"listMediaTypes", listMediaTypes, METH_VARARGS, NULL}, {"release", release, METH_VARARGS, NULL}, {"setResolution", setResolution, METH_VARARGS, NULL}, {"captureFrame", captureFrame, METH_VARARGS, NULL}, {"getWidth", getWidth, METH_VARARGS, NULL}, {"getHeight", getHeight, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL}};
https://github.com/yushulx/python-lite-camera
以上がPython カメラ SDK の構築とマルチバーコード スキャンへの使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。