首頁 後端開發 php教程 GIFDecoder的排錯以及修改另附完整程式碼和demo

GIFDecoder的排錯以及修改另附完整程式碼和demo

Aug 08, 2016 am 09:23 AM
buffer gif gt this

前言

好久沒有寫技術類的博客了,今天有些小的收穫,記錄下來,留作備份

Gif圖片的處理

由於業務需求,需要對gif動圖的第一幀進行截取,然後我就搜索,發現了GIFDecoder這樣的一個類,是做gif圖片的處理的,怎奈國內人博客環境還是那麼差,各種網站博客到處抄抄抄,沒有一個完整的內容,經過多個站的資料整理,終於能用了。

出現了異常

在運行demo的時候,遇到了顯示錯誤的問題

Notice: Undefined offset: 4 in /Applications/XAMPP/xamppfiles/htdocs/phptest/gifdecoderline.class.

查看源碼發現83行是這樣的

<code><span><span>function</span><span>GIFReadExtensions</span><span>()</span> {</span>
            GIFDecoder::GIFGetByte(<span>1</span>);
            <span>if</span> (<span>$this</span>-&gt;GIF_buffer [<span>0</span>] == <span>0xff</span>) {
                <span>for</span> (;;) {
                    GIFDecoder::GIFGetByte(<span>1</span>);
                    <span>if</span> (( <span>$u</span> = <span>$this</span>-&gt;GIF_buffer [<span>0</span>] ) == <span>0x00</span>) {
                        <span>break</span>;
                    }
                    GIFDecoder::GIFGetByte(<span>$u</span>);
                    <span>if</span> (<span>$u</span> == <span>0x03</span>) {
                        <span>$this</span>-&gt;GIF_anloop = ( <span>$this</span>-&gt;GIF_buffer [<span>1</span>] | <span>$this</span>-&gt;GIF_buffer [<span>2</span>] &lt;&lt; <span>8</span> );
                    }
                }
            } <span>else</span> {
                <span>for</span> (;;) {
                    GIFDecoder::GIFGetByte(<span>1</span>);
                    <span>if</span> (( <span>$u</span> = <span>$this</span>-&gt;GIF_buffer [<span>0</span>] ) == <span>0x00</span>) {
                        <span>break</span>;
                    }
                    GIFDecoder::GIFGetByte(<span>$u</span>);
                    <span>if</span> (<span>$u</span> == <span>0x04</span>) {
                        <span>if</span> (<span>$this</span>-&gt;GIF_buffer [<span>4</span>] &amp; <span>0x80</span>) {   <span>//这里是第83行</span><span>$this</span>-&gt;GIF_dispos [] = ( <span>$this</span>-&gt;GIF_buffer [<span>0</span>] &gt;&gt; <span>2</span> ) - <span>1</span>;
                        } <span>else</span> {
                            <span>$this</span>-&gt;GIF_dispos [] = ( <span>$this</span>-&gt;GIF_buffer [<span>0</span>] &gt;&gt; <span>2</span> ) - <span>0</span>;
                        }
                        <span>$this</span>-&gt;GIF_delays [] = ( <span>$this</span>-&gt;GIF_buffer [<span>1</span>] | <span>$this</span>-&gt;GIF_buffer [<span>2</span>] &lt;&lt; <span>8</span> );
                        <span>if</span> (<span>$this</span>-&gt;GIF_buffer [<span>3</span>]) {
                            <span>$this</span>-&gt;GIF_TransparentI = <span>$this</span>-&gt;GIF_buffer [<span>3</span>];
                        }
                    }
                }
            }
        }</code>
登入後複製

原因

經過搜尋引擎的努力,我得到的比較正規的解釋是

offset:接下去的數字是出錯的數組下標,一般是超出了一般是超出了陣列的值範圍,如定義了陣列

A[]A[] , : 錯誤數組的下標是從0開始的,所以這個陣列的下標就只能是0~9.所以,原因就是數組找不到下標為4的元素解決方案我們需要判斷下標為下標是不是存在

<code><span>if</span> (<span>isset</span>(<span>$this</span>-&gt;GIF_buffer [<span>4</span>]) &amp; <span>0x80</span>) { </code>
登入後複製
醬紫就搞定啦,啦啦啦~源碼
<code><span><span><span>&lt;?php</span>/**
 * GIFDecoder  &lt;br/&gt;
 * 
 * 日期: 2015年05月21日   &lt;br/&gt;
 * 原作者: 不详           &lt;br/&gt;
 * 修改: CalvinLee       &lt;br/&gt;
 * 
 * 
 * &lt;code&gt;
 * require_once("gifdecoder.class.php");
 *
 * $FIC = "test.gif";
 * //获取gif的第一帧进行保存
 * if (file_exists($FIC)) {
 *      $GIF_frame = fread(fopen($FIC, 'rb'), filesize($FIC));
 *      $decoder = new GIFDecoder($GIF_frame);
 *      $frames = $decoder-&gt;GIFGetFrames();
 *      $i = 0; 
 *      $fname =  rand(1000, 9999). $FIC . "_0$i.png"; 
 *      $hfic = fopen("" . $fname, "wb");
 *      fwrite($hfic, $frames [$i]);
 *      fclose($hfic);
 * } 
 *  &lt;/code&gt;
 * 
 * 
 *<span> @copyright</span> (c) 2015, Calvin Lee
 *<span> @author</span> Calvin Lee &lt;diandianxiyu_@live.cn&gt;

 */</span><span><span>Class</span><span>GIFDecoder</span> {</span><span>public</span><span>$GIF_TransparentR</span> = -<span>1</span>;
    <span>public</span><span>$GIF_TransparentG</span> = -<span>1</span>;
    <span>public</span><span>$GIF_TransparentB</span> = -<span>1</span>;
    <span>public</span><span>$GIF_TransparentI</span> = <span>0</span>;
    <span>public</span><span>$GIF_buffer</span> = <span>array</span>();
    <span>public</span><span>$GIF_arrays</span> = <span>array</span>();
    <span>public</span><span>$GIF_delays</span> = <span>array</span>();
    <span>public</span><span>$GIF_dispos</span> = <span>array</span>();
    <span>public</span><span>$GIF_stream</span> = <span>""</span>;
    <span>public</span><span>$GIF_string</span> = <span>""</span>;
    <span>public</span><span>$GIF_bfseek</span> = <span>0</span>;
    <span>public</span><span>$GIF_anloop</span> = <span>0</span>;
    <span>public</span><span>$GIF_screen</span> = <span>array</span>();
    <span>public</span><span>$GIF_global</span> = <span>array</span>();
    <span>public</span><span>$GIF_sorted</span>;
    <span>public</span><span>$GIF_colorS</span>;
    <span>public</span><span>$GIF_colorC</span>;
    <span>public</span><span>$GIF_colorF</span>;

    <span><span>function</span><span>GIFDecoder</span><span>(<span>$GIF_pointer</span>)</span> {</span><span>$this</span>-&gt;GIF_stream = <span>$GIF_pointer</span>;

        GIFDecoder::GIFGetByte(<span>6</span>);
        GIFDecoder::GIFGetByte(<span>7</span>);

        <span>$this</span>-&gt;GIF_screen = <span>$this</span>-&gt;GIF_buffer;
        <span>$this</span>-&gt;GIF_colorF = <span>$this</span>-&gt;GIF_buffer [<span>4</span>] &amp; <span>0x80</span> ? <span>1</span> : <span>0</span>;
        <span>$this</span>-&gt;GIF_sorted = <span>$this</span>-&gt;GIF_buffer [<span>4</span>] &amp; <span>0x08</span> ? <span>1</span> : <span>0</span>;
        <span>$this</span>-&gt;GIF_colorC = <span>$this</span>-&gt;GIF_buffer [<span>4</span>] &amp; <span>0x07</span>;
        <span>$this</span>-&gt;GIF_colorS = <span>2</span> &lt;&lt; <span>$this</span>-&gt;GIF_colorC;

        <span>if</span> (<span>$this</span>-&gt;GIF_colorF == <span>1</span>) {
            GIFDecoder::GIFGetByte(<span>3</span> * <span>$this</span>-&gt;GIF_colorS);
            <span>$this</span>-&gt;GIF_global = <span>$this</span>-&gt;GIF_buffer;
        }
        <span>for</span> (<span>$cycle</span> = <span>1</span>; <span>$cycle</span>;) {
            <span>if</span> (GIFDecoder::GIFGetByte(<span>1</span>)) {
                <span>switch</span> (<span>$this</span>-&gt;GIF_buffer [<span>0</span>]) {
                    <span>case</span><span>0x21</span>:
                        GIFDecoder::GIFReadExtensions();
                        <span>break</span>;
                    <span>case</span><span>0x2C</span>:
                        GIFDecoder::GIFReadDescriptor();
                        <span>break</span>;
                    <span>case</span><span>0x3B</span>:
                        <span>$cycle</span> = <span>0</span>;
                        <span>break</span>;
                }
            } <span>else</span> {
                <span>$cycle</span> = <span>0</span>;
            }
        }
    }

    <span><span>function</span><span>GIFReadExtensions</span><span>()</span> {</span>
        GIFDecoder::GIFGetByte(<span>1</span>);
        <span>if</span> (<span>$this</span>-&gt;GIF_buffer [<span>0</span>] == <span>0xff</span>) {
            <span>for</span> (;;) {
                GIFDecoder::GIFGetByte(<span>1</span>);
                <span>if</span> (( <span>$u</span> = <span>$this</span>-&gt;GIF_buffer [<span>0</span>] ) == <span>0x00</span>) {
                    <span>break</span>;
                }
                GIFDecoder::GIFGetByte(<span>$u</span>);
                <span>if</span> (<span>$u</span> == <span>0x03</span>) {
                    <span>$this</span>-&gt;GIF_anloop = ( <span>$this</span>-&gt;GIF_buffer [<span>1</span>] | <span>$this</span>-&gt;GIF_buffer [<span>2</span>] &lt;&lt; <span>8</span> );
                }
            }
        } <span>else</span> {
            <span>for</span> (;;) {
                GIFDecoder::GIFGetByte(<span>1</span>);
                <span>if</span> (( <span>$u</span> = <span>$this</span>-&gt;GIF_buffer [<span>0</span>] ) == <span>0x00</span>) {
                    <span>break</span>;
                }
                GIFDecoder::GIFGetByte(<span>$u</span>);
                <span>if</span> (<span>$u</span> == <span>0x04</span>) {
                    <span>if</span> (<span>isset</span>(<span>$this</span>-&gt;GIF_buffer [<span>4</span>]) &amp; <span>0x80</span>) {
                        <span>$this</span>-&gt;GIF_dispos [] = ( <span>$this</span>-&gt;GIF_buffer [<span>0</span>] &gt;&gt; <span>2</span> ) - <span>1</span>;
                    } <span>else</span> {
                        <span>$this</span>-&gt;GIF_dispos [] = ( <span>$this</span>-&gt;GIF_buffer [<span>0</span>] &gt;&gt; <span>2</span> ) - <span>0</span>;
                    }
                    <span>$this</span>-&gt;GIF_delays [] = ( <span>$this</span>-&gt;GIF_buffer [<span>1</span>] | <span>$this</span>-&gt;GIF_buffer [<span>2</span>] &lt;&lt; <span>8</span> );
                    <span>if</span> (<span>$this</span>-&gt;GIF_buffer [<span>3</span>]) {
                        <span>$this</span>-&gt;GIF_TransparentI = <span>$this</span>-&gt;GIF_buffer [<span>3</span>];
                    }
                }
            }
        }
    }

    <span><span>function</span><span>GIFReadDescriptor</span><span>()</span> {</span><span>$GIF_screen</span> = <span>Array</span>();

        GIFDecoder::GIFGetByte(<span>9</span>);
        <span>$GIF_screen</span> = <span>$this</span>-&gt;GIF_buffer;
        <span>$GIF_colorF</span> = <span>$this</span>-&gt;GIF_buffer [<span>8</span>] &amp; <span>0x80</span> ? <span>1</span> : <span>0</span>;
        <span>if</span> (<span>$GIF_colorF</span>) {
            <span>$GIF_code</span> = <span>$this</span>-&gt;GIF_buffer [<span>8</span>] &amp; <span>0x07</span>;
            <span>$GIF_sort</span> = <span>$this</span>-&gt;GIF_buffer [<span>8</span>] &amp; <span>0x20</span> ? <span>1</span> : <span>0</span>;
        } <span>else</span> {
            <span>$GIF_code</span> = <span>$this</span>-&gt;GIF_colorC;
            <span>$GIF_sort</span> = <span>$this</span>-&gt;GIF_sorted;
        }
        <span>$GIF_size</span> = <span>2</span> &lt;&lt; <span>$GIF_code</span>;
        <span>$this</span>-&gt;GIF_screen [<span>4</span>] &amp;= <span>0x70</span>;
        <span>$this</span>-&gt;GIF_screen [<span>4</span>] |= <span>0x80</span>;
        <span>$this</span>-&gt;GIF_screen [<span>4</span>] |= <span>$GIF_code</span>;
        <span>if</span> (<span>$GIF_sort</span>) {
            <span>$this</span>-&gt;GIF_screen [<span>4</span>] |= <span>0x08</span>;
        }

        <span>//GIF Data Begin</span><span>if</span> (<span>$this</span>-&gt;GIF_TransparentI) {
            <span>$this</span>-&gt;GIF_string = <span>"GIF89a"</span>;
        } <span>else</span> {
            <span>$this</span>-&gt;GIF_string = <span>"GIF87a"</span>;
        }
        GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_screen);
        <span>if</span> (<span>$GIF_colorF</span> == <span>1</span>) {
            GIFDecoder::GIFGetByte(<span>3</span> * <span>$GIF_size</span>);
            <span>if</span> (<span>$this</span>-&gt;GIF_TransparentI) {
                <span>$this</span>-&gt;GIF_TransparentR = <span>$this</span>-&gt;GIF_buffer [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>0</span>];
                <span>$this</span>-&gt;GIF_TransparentG = <span>$this</span>-&gt;GIF_buffer [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>1</span>];
                <span>$this</span>-&gt;GIF_TransparentB = <span>$this</span>-&gt;GIF_buffer [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>2</span>];
            }
            GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_buffer);
        } <span>else</span> {
            <span>if</span> (<span>$this</span>-&gt;GIF_TransparentI) {
                <span>$this</span>-&gt;GIF_TransparentR = <span>$this</span>-&gt;GIF_global [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>0</span>];
                <span>$this</span>-&gt;GIF_TransparentG = <span>$this</span>-&gt;GIF_global [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>1</span>];
                <span>$this</span>-&gt;GIF_TransparentB = <span>$this</span>-&gt;GIF_global [<span>3</span> * <span>$this</span>-&gt;GIF_TransparentI + <span>2</span>];
            }
            GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_global);
        }
        <span>if</span> (<span>$this</span>-&gt;GIF_TransparentI) {
            <span>$this</span>-&gt;GIF_string .= <span>"!\xF9\x04\x1\x0\x0"</span> . chr(<span>$this</span>-&gt;GIF_TransparentI) . <span>"\x0"</span>;
        }
        <span>$this</span>-&gt;GIF_string .= chr(<span>0x2C</span>);
        <span>$GIF_screen</span> [<span>8</span>] &amp;= <span>0x40</span>;
        GIFDecoder::GIFPutByte(<span>$GIF_screen</span>);
        GIFDecoder::GIFGetByte(<span>1</span>);
        GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_buffer);
        <span>for</span> (;;) {
            GIFDecoder::GIFGetByte(<span>1</span>);
            GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_buffer);
            <span>if</span> (( <span>$u</span> = <span>$this</span>-&gt;GIF_buffer [<span>0</span>] ) == <span>0x00</span>) {
                <span>break</span>;
            }
            GIFDecoder::GIFGetByte(<span>$u</span>);
            GIFDecoder::GIFPutByte(<span>$this</span>-&gt;GIF_buffer);
        }
        <span>$this</span>-&gt;GIF_string .= chr(<span>0x3B</span>);
        <span>//GIF Data End</span><span>$gif_array</span> = &amp;<span>$this</span>-&gt;GIF_arrays;
        <span>$gif_array</span>[] = <span>$this</span>-&gt;GIF_string;
    }

    <span><span>function</span><span>GIFGetByte</span><span>(<span>$len</span>)</span> {</span><span>$this</span>-&gt;GIF_buffer = <span>Array</span>();
        <span>for</span> (<span>$i</span> = <span>0</span>; <span>$i</span> &lt; <span>$len</span>; <span>$i</span>++) {
            <span>if</span> (<span>$this</span>-&gt;GIF_bfseek &gt; strlen(<span>$this</span>-&gt;GIF_stream)) {
                <span>return</span><span>0</span>;
            }
            <span>$this</span>-&gt;GIF_buffer[] = ord(<span>$this</span>-&gt;GIF_stream { <span>$this</span>-&gt;GIF_bfseek++});
        }
        <span>return</span><span>1</span>;
    }

    <span><span>function</span><span>GIFPutByte</span><span>(<span>$bytes</span>)</span> {</span><span>foreach</span> (<span>$bytes</span><span>as</span><span>$byte</span>) {
            <span>$this</span>-&gt;GIF_string .= chr(<span>$byte</span>);
        }
    }

    <span><span>function</span><span>GIFGetFrames</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_arrays );
    }

    <span><span>function</span><span>GIFGetDelays</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_delays );
    }

    <span><span>function</span><span>GIFGetLoop</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_anloop );
    }

    <span><span>function</span><span>GIFGetDisposal</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_dispos );
    }

    <span><span>function</span><span>GIFGetTransparentR</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_TransparentR );
    }

    <span><span>function</span><span>GIFGetTransparentG</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_TransparentG );
    }

    <span><span>function</span><span>GIFGetTransparentB</span><span>()</span> {</span><span>return</span> ( <span>$this</span>-&gt;GIF_TransparentB );
    }

}

<span>?&gt;</span></span></span></code>
登入後複製

後記

小的知識累積最後會有質變

得不一樣,如果還一樣的話那就是自己的問題了

以上就介紹了GIFDecoder的排錯以及修改另附完整程式碼和demo,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章標籤

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

華為GT3 Pro和GT4的差異是什麼? 華為GT3 Pro和GT4的差異是什麼? Dec 29, 2023 pm 02:27 PM

華為GT3 Pro和GT4的差異是什麼?

修復:截圖工具在 Windows 11 中不起作用 修復:截圖工具在 Windows 11 中不起作用 Aug 24, 2023 am 09:48 AM

修復:截圖工具在 Windows 11 中不起作用

如何修復無法連線到iPhone上的App Store錯誤 如何修復無法連線到iPhone上的App Store錯誤 Jul 29, 2023 am 08:22 AM

如何修復無法連線到iPhone上的App Store錯誤

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决

watch4pro好還是gt好 watch4pro好還是gt好 Sep 26, 2023 pm 02:45 PM

watch4pro好還是gt好

java中Buffer的概念是什麼 java中Buffer的概念是什麼 Apr 28, 2023 pm 05:13 PM

java中Buffer的概念是什麼

如何使用 iPadOS 17.4 優化 iPad 電池壽命 如何使用 iPadOS 17.4 優化 iPad 電池壽命 Mar 21, 2024 pm 10:31 PM

如何使用 iPadOS 17.4 優化 iPad 電池壽命

一篇搞懂this指向,追趕70%的前端人 一篇搞懂this指向,追趕70%的前端人 Sep 06, 2022 pm 05:03 PM

一篇搞懂this指向,追趕70%的前端人

See all articles