php扩展开发笔记(10)自定义 libpng 库中的 IO 函数,将图片写入内存
在开发这个生成二维码扩展 dcode 的时候,需要将生成的二维码 png 图片以字符串的方式返回给调用者,而不是直接生成文件,这样比较方便的是不用去操作文件,将文件的操作完全交给用户。
生成图片采用了 libpng 的库,关于 libpng 的文档大家可以到 这里 png 文档 看。我使用这个库在 Ubuntu14.04 上编译我的扩展的时候还有个小问题 png_create_write_struct in Unknown on line 0 on ubuntu 14,到网上一搜索,还是非常常见的。
下面简单的列一下代码:
<code><span>/** {{{ dcode_png_writer() * function is custom png_write callback function * Return void */</span><span>static</span><span>void</span> dcode_png_writer(png_structp png_ptr, png_bytep data, png_size_t length) { png_mem_encode* p = (png_mem_encode*) png_get_io_ptr(png_ptr); size_t nsize = p->size + length; <span>if</span> (p->buffer) p->buffer = erealloc(p->buffer, nsize); <span>else</span> p->buffer = emalloc(nsize); <span>if</span> (!p->buffer) { png_error(png_ptr, <span>"PNG allocate memory error"</span>); <span>exit</span>(FAILURE); } <span>memcpy</span>(p->buffer + p->size, data, length); p->size += length; } <span>/* }}} */</span></code>
<code><span>/** {{{ dcode_write_to_png() * write qrcode struct to memory * Return char* */</span><span>static</span><span>char</span>* dcode_write_to_png(QRcode *qrcode, <span>int</span> size, <span>int</span> margin, <span>int</span> *pp_len) { png_structp png_ptr; png_infop info_ptr; <span>unsigned</span><span>char</span> *row, *p, *q; <span>int</span> x, y, xx, yy, bit; <span>int</span> realwidth; realwidth = (qrcode->width + margin * <span>2</span>) * size; <span>int</span> row_fill_len = (realwidth + <span>7</span>) / <span>8</span>; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); <span>if</span> (png_ptr == NULL) { php_error(E_ERROR, <span>"Failed to initialize PNG writer"</span>); <span>return</span> NULL; } info_ptr = png_create_info_struct(png_ptr); <span>if</span> (info_ptr == NULL) { php_error(E_ERROR, <span>"Failed to initialize PNG info"</span>); <span>return</span> NULL; } <span>if</span> (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); php_error(E_ERROR, <span>"Failed to set PNG jmpbuf"</span>); <span>return</span> NULL; } row = (<span>unsigned</span><span>char</span> *) emalloc(row_fill_len); <span>if</span> (row == NULL) { png_destroy_write_struct(&png_ptr, &info_ptr); php_error(E_ERROR, <span>"Failed to allocate memory"</span>); <span>return</span> NULL; } png_mem_encode state = {NULL, <span>0</span>}; png_set_write_fn(png_ptr, &state, &dcode_png_writer, NULL); png_set_IHDR(png_ptr, info_ptr, realwidth, realwidth, <span>1</span>, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); <span>memset</span>(row, <span>0xff</span>, (realwidth + <span>7</span>) / <span>8</span>); <span>for</span>(y = <span>0</span>; y data; <span>for</span>(y = <span>0</span>; y width; y ++) { bit = <span>7</span>; <span>memset</span>(row, <span>0xff</span>, (realwidth + <span>7</span>) / <span>8</span>); q = row; q += margin * size / <span>8</span>; bit = <span>7</span> - (margin * size % <span>8</span>); <span>for</span>(x = <span>0</span>; x width; x ++) { <span>for</span>(xx = <span>0</span>; xx <size xx>1) if(bit 0) { q++; bit = <span>7</span>; } } p++; } <span>for</span>(yy = <span>0</span>; yy memset(row, <span>0xff</span>, (realwidth + <span>7</span>) / <span>8</span>); <span>for</span>(y = <span>0</span>; y char *bin_data = NULL; <span>if</span> (state.buffer) { bin_data = estrndup(state.buffer, state.size); *pp_len = state.size; efree(state.buffer); } <span>return</span> bin_data; } <span>/** }}} */</span></size></code>
- 第一个函数
dcode_png_writer
是自定义的写 png 数据的 callback 函数。 - 第二个函数
dcode_write_to_png
是将 QRcode 数据写入 png
主要可以看下这个部分
<code>png_set_write_fn(png_ptr, &state, &dcode_png_writer, NULL);</code>
这个地方就是调用了自定义的 write 函数 dcode_png_writer
,将数据写到了 state
这个结构体里,state
结构体如下
<code><span>typedef</span><span>struct</span> _png_mem_encode { <span>char</span> *buffer; size_t size; } png_mem_encode ;</code>
png_set_write_fn
函数设置了自定义的 write 函数,通过 dcode_png_writer
来像 state 写入数据,动态的来分配内存。
关于 png_set_write_fn
的定义,可以参看上面提到的 PNG 文档,自定义函数还可以自定义错误处理等功能,这样可以根据实际情况来接管 error handler
而不是让其在内部退出。更多的相关代码请看 DCode 扩展
生成 QRCode 的速度还是很快的,如果用 for ($i = 0; $i 的 <code>$i
作为参数,3秒就能生成 10000 个。
版权声明:本文为博主原创文章,未经博主允许不得转载。
以上就介绍了php扩展开发笔记(10)自定义 libpng 库中的 IO 函数,将图片写入内存,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment convertir PNG en JPG sous Windows 11 Sous Windows 10 et 11, vous pouvez utiliser l'application Paint intégrée de Microsoft pour convertir rapidement des fichiers image. Pour convertir une image PNG en JPG sous Windows 11, procédez comme suit : Ouvrez l'Explorateur de fichiers et accédez à l'image PNG que vous souhaitez convertir. Cliquez avec le bouton droit sur l'image et sélectionnez Ouvrir avec > Dessiner dans le menu. Votre photo ou image s'ouvre dans l'application Paint. Notez la taille du fichier en bas de l'écran. Pour convertir un fichier PNG en JPG, cliquez sur Fichier et sélectionnez Enregistrer sous > Image JPEG dans le menu. Lorsque la ressource de fichier

Utilisez la fonction File.length() de Java pour obtenir la taille d'un fichier. La taille du fichier est une exigence très courante lors des opérations sur les fichiers. Java fournit un moyen très pratique d'obtenir la taille d'un fichier, c'est-à-dire en utilisant la longueur (. ) méthode de la classe File . Cet article explique comment utiliser cette méthode pour obtenir la taille d'un fichier et donne des exemples de code correspondants. Tout d’abord, nous devons créer un objet File pour représenter le fichier dont nous voulons obtenir la taille. Voici comment créer un objet File : Filef

La différence entre null et NULL en langage C est la suivante : null est une définition de macro en langage C, généralement utilisée pour représenter un pointeur nul, qui peut être utilisé pour initialiser des variables de pointeur ou pour déterminer si le pointeur est nul dans une instruction conditionnelle ; NULL est une définition de macro en langage C. Une constante prédéfinie dans , généralement utilisée pour représenter une valeur nulle, utilisée pour représenter un pointeur nul, un tableau de pointeurs nuls ou un pointeur de structure nulle.

En JavaScript, non défini et null représentent le concept de « rien » : 1. undéfini représente une variable non initialisée ou une propriété inexistante lorsqu'une variable est déclarée mais qu'aucune valeur ne lui est attribuée, la valeur de la variable est undéfinie. lors de l'accès à des propriétés qui n'existent pas dans l'objet, la valeur renvoyée est également indéfinie ; 2. null représente une référence d'objet vide Dans certains cas, la référence d'objet peut être définie sur null pour libérer la mémoire qu'elle occupe.

Supposons que vous deviez renommer l'extension d'un fichier d'une extension à une autre, par exemple jpg en png. C'est facile, bien sûr ! Mais que se passe-t-il si vous avez plusieurs fichiers dont les extensions doivent être modifiées ? Ou pire, que se passe-t-il si ces multiples fichiers se trouvent également dans plusieurs dossiers et sous-dossiers, au sein d’un seul dossier ? Eh bien, pour une personne normale, cela peut être un cauchemar. Mais pour un geek, absolument pas. La question est maintenant : êtes-vous un geek ? Eh bien, avec l’aide de Geek Page, c’est définitivement le cas ! Dans cet article, nous expliquons comment renommer facilement l'extension de tous les fichiers d'un dossier, y compris les sous-dossiers de votre choix, d'une extension à une autre via une méthode de script batch. Avis:

Null et indéfini indiquent tous deux un manque de valeur ou un état indéfini. Selon le scénario d'utilisation, il existe quelques principes directeurs pour choisir d'utiliser null ou undefined : 1. Lorsque vous devez indiquer clairement qu'une variable est vide ou non valide. peut utiliser null ; 2. Lorsqu'une variable a été déclarée mais qu'aucune valeur n'a encore été attribuée, elle sera définie sur non définie par défaut. 3. Lorsque vous devez vérifier si une variable est vide ou non définie, utilisez l'opérateur d'égalité stricte "= ; ==" pour déterminer si la variable est nulle ou indéfinie. .

La différence entre null et non défini est : 1. Signification sémantique ; 2. Scénarios d'utilisation ; 3. Comparaison avec d'autres valeurs ; 4. Relation avec les paramètres de fonction ; . Performances dans la sérialisation JSON ; 9. Relation avec les types. Introduction détaillée : 1. Signification sémantique, null signifie généralement savoir que cette variable n'aura aucune valeur d'objet valide, tandis qu'undéfini signifie généralement que la variable n'a pas reçu de valeur ou que l'objet n'a pas cet attribut ; , etc.

L'écriture en python est une méthode d'écriture d'une chaîne dans un fichier. Le format de syntaxe est "fileObject.write([str])", où str fait référence à la chaîne à écrire dans le fichier.
