在开发这个生成二维码扩展 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教程有兴趣的朋友有所帮助。

tomakephpapplicationsfaster,关注台词:1)useopcodeCachingLikeLikeLikeLikeLikePachetoStorePreciledScompiledScriptbyTecode.2)MinimimiedAtabaseSqueriSegrieSqueriSegeriSybysequeryCachingandeffeftExting.3)Leveragephp7 leveragephp7 leveragephp7 leveragephpphp7功能forbettercodeefficy.4)

到ImprovephPapplicationspeed,关注台词:1)启用opcodeCachingwithapCutoredUcescriptexecutiontime.2)实现databasequerycachingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandredececonnection.4 limitsclection.4.4

依赖注入(DI)通过显式传递依赖关系,显着提升了PHP代码的可测试性。 1)DI解耦类与具体实现,使测试和维护更灵活。 2)三种类型中,构造函数注入明确表达依赖,保持状态一致。 3)使用DI容器管理复杂依赖,提升代码质量和开发效率。

databasequeryOptimizationinphpinvolVolVOLVESEVERSEVERSTRATEMIESOENHANCEPERANCE.1)SELECTONLYNLYNESSERSAYCOLUMNSTORMONTOUMTOUNSOUDSATATATATATATATATATATRANSFER.3)

phpisusedforsenderemailsduetoitsbuilt-inmail()函数andsupportiveLibrariesLikePhpMailerandSwiftMailer.1)usethemail()functionforbasicemails,butithasimails.2)butithasimimitations.2)

PHP性能瓶颈可以通过以下步骤解决:1)使用Xdebug或Blackfire进行性能分析,找出问题所在;2)优化数据库查询并使用缓存,如APCu;3)使用array_filter等高效函数优化数组操作;4)配置OPcache进行字节码缓存;5)优化前端,如减少HTTP请求和优化图片;6)持续监控和优化性能。通过这些方法,可以显着提升PHP应用的性能。

依赖性注射(DI)InphpisadesignPatternthatManages和ReducesClassDeptions,增强量产生性,可验证性和Maintainability.itallowspasspassingDepentenciesLikEdenceSeconnectionSeconnectionStoclasseconnectionStoclasseSasasasasareTers,interitationApertatingAeseritatingEaseTestingEasingEaseTeStingEasingAndScalability。

cachingimprovesphpermenceByStorcyResultSofComputationsorqucrouctationsorquctationsorquickretrieval,reducingServerLoadAndenHancingResponsetimes.feftectivestrategiesinclude:1)opcodecaching,whereStoresCompiledSinmememorytssinmemorytoskipcompliation; 2)datacaching datacachingsingMemccachingmcachingmcachings


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

WebStorm Mac版
好用的JavaScript开发工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具