Heim > Backend-Entwicklung > PHP-Tutorial > Entwicklungshinweise zur PHP-Erweiterung (10) Passen Sie die IO-Funktion in der libpng-Bibliothek an, um Bilder in den Speicher zu schreiben

Entwicklungshinweise zur PHP-Erweiterung (10) Passen Sie die IO-Funktion in der libpng-Bibliothek an, um Bilder in den Speicher zu schreiben

WBOY
Freigeben: 2016-08-08 09:21:34
Original
1448 Leute haben es durchsucht

Bei der Entwicklung dieser QR-Code-Erweiterung dcode ist es notwendig, das generierte QR-Code-PNG-Bild in Form einer Zeichenfolge an den Anrufer zurückzugeben, anstatt direkt eine Datei zu generieren. Dies ist praktischer, da keine Notwendigkeit besteht um Dateien zu manipulieren und die Bedienung der Dateien vollständig dem Benutzer zu überlassen.

Die libpng-Bibliothek wird zum Generieren von Bildern verwendet. Für Dokumente zu libpng können Sie hier zum PNG-Dokument gehen. Als ich diese Bibliothek zum Kompilieren meiner Erweiterung unter Ubuntu 14.04 verwendete, hatte ich immer noch ein kleines Problem: png_create_write_struct in „Unknown“ in Zeile 0 unter Ubuntu 14. Nach der Suche im Internet ist es immer noch sehr häufig.

Der Code ist unten einfach aufgeführt:

<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>
Nach dem Login kopieren
<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 < margin * size; y ++) {
        png_write_row(png_ptr, row);
    }

    p = qrcode->data;
    <span>for</span>(y = <span>0</span>; y < qrcode->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 < qrcode->width; x ++) {
            <span>for</span>(xx = <span>0</span>; xx <size; xx ++) {
                *q ^= (*p & <span>1</span>) << bit;
                bit--;
                <span>if</span>(bit < <span>0</span>) {
                    q++;
                    bit = <span>7</span>;
                }
            }
            p++;
        }
        <span>for</span>(yy = <span>0</span>; yy < size; yy ++ ) {
            png_write_row(png_ptr, row);
        }
    }

    <span>memset</span>(row, <span>0xff</span>, (realwidth + <span>7</span>) / <span>8</span>);
    <span>for</span>(y = <span>0</span>; y < margin * size; y ++) {
        png_write_row(png_ptr, row);
    }

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    efree(row);

    <span>char</span> *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></code>
Nach dem Login kopieren
  1. Die erste Funktion dcode_png_writer ist eine benutzerdefinierte Rückruffunktion zum Schreiben von PNG-Daten.
  2. Die zweite Funktion dcode_write_to_png besteht darin, QRcode-Daten in PNG zu schreiben

Sie können sich hauptsächlich diesen Teil ansehen

<code>png_set_write_fn(png_ptr, &state, &dcode_png_writer, NULL);</code>
Nach dem Login kopieren

Dieser Ort nennt das Selbst The Die definierte Schreibfunktion dcode_png_writer schreibt Daten in die Struktur state. Die Struktur state lautet wie folgt: Die Funktion

<code><span>typedef</span><span>struct</span> _png_mem_encode {
    <span>char</span> *buffer;
    size_t size;
} png_mem_encode ;</code>
Nach dem Login kopieren

png_set_write_fn legt eine benutzerdefinierte Schreibfunktion fest, um Daten über dcode_png_writer zu schreiben wie Zustand und dynamisch Speicher zuweisen.

Für die Definition von png_set_write_fn können Sie sich auf das oben erwähnte PNG-Dokument beziehen. Benutzerdefinierte Funktionen können auch die Fehlerbehandlung und andere Funktionen anpassen, sodass error handler stattdessen entsprechend der tatsächlichen Situation übernommen werden kann es intern beenden zu lassen. Weitere verwandte Codes finden Sie in der DCode-Erweiterung

. Die Geschwindigkeit der QRCode-Generierung ist immer noch sehr hoch. Wenn Sie for ($i = 0; $i < 10000; $i ) und $i als Parameter verwenden, können 10.000 QRCodes in 3 Sekunden generiert werden.

Urheberrechtserklärung: Dieser Artikel ist ein Originalartikel des Bloggers und darf nicht ohne die Erlaubnis des Bloggers reproduziert werden.

Das Obige stellt die Entwicklungshinweise zur PHP-Erweiterung vor (10). Passen Sie die IO-Funktion in der libpng-Bibliothek an und schreiben Sie Bilder in den Speicher, einschließlich des Inhalts. Ich hoffe, dass dies für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage