| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 | <?php/** * Created by PhpStorm. * User: tandunzhao * Date: 2018/1/19 * Time: 上午9:47 */namespace App\Libs;use App\Modules\Book\Services\ChapterImageService;use App\Modules\Book\Services\ChapterService;use Log;use Hashids;class ChapterToImage{    public static function createChapterImage($bookId, $style = 0,$chapters) {        //$chapters = ChapterService::getTopFiveChapter($bookId);        foreach ($chapters as $chapter) {            //画标题            if(ChapterImageService::getChapterImage($chapter['bid'],[$chapter['id']])->count()){            }else{                self::drawTxt(self::to_unicode($chapter['name']), $chapter['bid'], $chapter['sequence'], $chapter['id'], -1, $style);                $content = str_replace($chapter['name'],'',$chapter['content']);                self::createChapterContentToImage(self::to_unicode($content), $chapter['bid'], $chapter['sequence'], $chapter['id'], $style);            }        }        $imagePath = public_path("chapter");        self::del_dir($imagePath);    }    private static function createChapterContentToImage($inputString, $bookId, $sequence, $chapterId, $style = 0) {        if(!$inputString || empty($inputString)) {            $inputString = "";        }        $inputStrings = explode("\n", $inputString);        $imageIndex = 1;        if(sizeof($inputStrings) < 5) {            self::drawTxt($inputString, $bookId, $sequence, $chapterId, $imageIndex, $style);        } else {            $imageTextString = "";            $index = 1;            foreach ($inputStrings as $strTmp) {                $strTmp = self::trimAllSpace($strTmp);                if($strTmp && !empty($strTmp)) {                    $imageTextString .= $strTmp."\n";                    if($index % 4 == 0) {                        self::drawTxt($imageTextString, $bookId, $sequence, $chapterId, $imageIndex, $style);                        $imageIndex++;                        $imageTextString = "";                        $index = 0;                    }                    $index++;                } else {                }            }            if(!empty($imageTextString)) {                self::drawTxt($imageTextString, $bookId, $sequence, $chapterId, $imageIndex, $style);            }        }    }    private static function drawTxt($inputString, $bookId, $sequence, $chapterId, $index, $style = 0) {        if(!$inputString || empty($inputString)) {            $inputString = "";        }        $width = 640;        $temp = array("color" => array(1, 1, 1), "font-size" =>32, "width" => $width, "left" => 0, "top" => 15 ,"hang-size" => 35, "duan-size" => 10);        $bg = imagecreatetruecolor($width, 90); // 创建画布        $str_height = self::drawTxtToImage($bg, $temp, $inputString, false);        imagedestroy($bg);        $im = ImageCreate($width, $str_height);        $bgA = imagecolorallocate($im, 255, 255, 255);        $str_h = self::drawTxtToImage($im, $temp, $inputString, true);        $imagePath = public_path("chapter/".$bookId."/".$sequence."/");        $dir = iconv("UTF-8", "UTF-8", $imagePath);        if (!file_exists($dir)){            mkdir ($dir,0777,true);        }        $imagePath .= $index."_".$style."_".time().".jpg";        imagepng($im, $imagePath);        imagedestroy($im);        Log::info($imagePath);//        Log::info("书ID[".$bookId."]章节ID[".$chapterId."] ".$imagePath."      ".date("y-m-d H:i:s"."\n"));        $ossPath = "book_chapter_image_new/" . Hashids::encode($bookId) . "/" . $sequence . "/" . $index."_".$style."_".time(). ".jpg";        if(env('PAYMENT_AUTO_PAY_TEST') != 2) {            $ossPath = "book_chapter_image_test/" . Hashids::encode($bookId) . "/" . $sequence . "/" . $index."_".$style."_".time() . ".jpg";        }        $imageUrl = AliOSS::uploadImg($ossPath, $imagePath);//        Log::info("".$imageUrl."      ".date("y-m-d H:i:s"."\n"));        $imageUrl = str_ireplace('zhuishuyun.oss-cn-hangzhou.aliyuncs.com','cdn-novel.iycdm.com',$imageUrl);        ChapterImageService::save($bookId, $chapterId, $sequence, $index, $imageUrl);    }    private static function drawTxtToImage($card, $pos, $inputString, $isWrite) {        if(!$inputString || empty($inputString)) {            $inputString = "";        }        $width = $pos["width"];        $fontSize = $pos["font-size"];        $fontFile = self::getFontFile();        $fontColor = imagecolorallocate($card, $pos["color"][0], $pos["color"][1], $pos["color"][2]);        $textOneWidth = self::getTextOneWidth($pos);        $textOneWidthAndPace = self::getTextOneWidthAndPace($pos);        $marginLeft = $pos["left"] + $textOneWidth * 0.5;        $width = $width - $pos["left"] - $textOneWidth;        $duanSize = $pos["duan-size"];        $hangSize = $pos["hang-size"];        $lineTextHeight = self::getTextLineHeight($pos);        $_str_h = $lineTextHeight * 0.8 + $pos["top"];        $textHeight = $pos["top"];//        $textHeight += $hangSize;//        $textHeight += $lineTextHeight;        $inputStrings = explode("\n", $inputString);        foreach ($inputStrings as $strTmp) {            $strTmp = self::trimAllSpace($strTmp);            if(empty($strTmp)) {                continue;            }            //CentOS 服务器上生成图片,一个空格 算一个汉字的长度,暂时测试是这样的            $strTmp = "  ".$strTmp;            $drawTextStr = "";            $letter = [];            for ($i=0;$i<mb_strlen($strTmp);$i++) {                $letter[] = mb_substr($strTmp, $i, 1);            }            $ttfText = imagettftext($card, $fontSize, 0, 0, -$lineTextHeight, $fontColor, $fontFile, $strTmp);//            dd($ttfText);//            Log::info("".$ttfText[2]."  ===  ".$strTmp);            if($ttfText[2] <= $width) {                $textHeight += $hangSize;                $textHeight += $lineTextHeight;                $drawTextStr = $strTmp;            } else {                $lineNum = 0;                $content = "";                for ($i=0; $i<sizeof($letter); $i++) {                    $content .= $letter[$i];                    $ttfText = imagettftext($card, $fontSize, 0, $marginLeft, -$lineTextHeight, $fontColor, $fontFile, $content);//                    if(strpos($drawTextStr,"记忆里还有几道模糊的影,") !== false){//                        Log::error("图片高度 01  ===  ".$drawTextStr  ."   ===    ". $content . "    ".$ttfText[2]."  width= ".$width);//                    }//                    if(strpos($drawTextStr,"心里清楚厉墨风回来过了") !== false){//                        Log::error("图片高度 1  ===  ".$drawTextStr  ."   ===    ". $content . "    ".$ttfText[2]."  width= ".$width);//                        Log::error("图片高度 2 ===  lineNum = ".$lineNum. "    (sizeof(letter) = ". sizeof($letter) . "  (i + 1) = "  .($i + 1). "    ".((sizeof($letter) == ($i + 1)) && $lineNum > 0));//                    }                    if($ttfText[2] > $width) {//                        dd($width);//                        dd($content);//                        dd($ttfText);                        $drawTextStr.="\\n";                        $textHeight += $hangSize;                        $textHeight += $lineTextHeight;                        $content = "";                        $lineNum++;                        if((sizeof($letter) == ($i + 1)) && $lineNum > 0) {                            $textHeight += $hangSize;                            $textHeight += $lineTextHeight;                            $lineNum++;                        }                    } else {                        if((sizeof($letter) == ($i + 1)) && $lineNum > 0) {                            $textHeight += $hangSize;                            $textHeight += $lineTextHeight;                            $lineNum++;                        }                    }                    $drawTextStr .= ($letter[$i]."");                }            }            if ($isWrite) {                $drawTextStrs = explode("\\n", $drawTextStr);                $lineIndex = 0;                foreach ($drawTextStrs as $lee) {                    $ttfText = imagettftext($card, $fontSize, 0, $marginLeft, $_str_h, $fontColor, $fontFile, $lee);                    $_str_h += $lineTextHeight;                    $_str_h += $hangSize;                    $lineIndex++;                }                $_str_h += $duanSize;            }            $textHeight += $duanSize;        }        return $textHeight;    }    private static function getTextLineHeight($pos) {        $fontSize = $pos["font-size"];        $fontFile = self::getFontFile();        $ttfBoxTemp = imagettfbbox($fontSize, 0, $fontFile, self::to_unicode("啊"));        $textHeight = $height = ($ttfBoxTemp[3] - $ttfBoxTemp[5]);        return $textHeight;    }    private static function getTextOneWidth($pos) {        $fontSize = $pos["font-size"];        $fontFile = self::getFontFile();        $ttfBoxTemp = imagettfbbox($fontSize, 0, $fontFile, self::to_unicode("啊"));        $textWidth = $width = ($ttfBoxTemp[4] - $ttfBoxTemp[6]);        $textWidth = $textWidth;        return $textWidth;    }    private static function to_unicode($string)    {//        $str = mb_convert_encoding($string, 'UCS-2', 'UTF-8');//        $arrstr = str_split($str, 2);//        $unistr = '';//        foreach ($arrstr as $n) {//            $dec = hexdec(bin2hex($n));//            $unistr .= '&#' . $dec . ';';//        }//        return $unistr;//        $arr = mb_convert_encoding($string, "html-entities","utf-8");//        return $arr;        return $string;    }    private static function getTextOneWidthAndPace($pos) {        $textWidth = self::getTextOneWidth($pos);        $textWidth = $textWidth +  $textWidth / 9;        return $textWidth;    }    private static function getFontFile() {        return public_path('fonts/jdytj.TTF');    }    private static function trimAllSpace($str) {        $str = trim($str);        $str = str_replace(" ","",$str);        $str = str_replace("  ","",$str);        $str = str_replace("   ","",$str);        $str = str_replace("    ","",$str);        $str = str_replace(" ","",$str);        $str = str_replace("\t","",$str);        $str = str_replace("\n","",$str);        $str = str_replace("    ","",$str);        $str = preg_replace("/\t/","", $str);        $str = preg_replace("/\r/","",$str);        $str = preg_replace("/\n/","",$str);        $str = preg_replace("/\r\n/","",$str);        $str = preg_replace("/ /","",$str);        $str = preg_replace("/  /","",$str);        $str = preg_replace('/($s*$)|(^s*^)/m', '',$str);        $str = preg_replace("/,/",",", $str);        return trim($str); //返回字符串    }    private static function del_dir($dir) {        //TODO 重要操作,仔细检测        if(strpos($dir, "zhuishuyun/public/chapter") !== false) {            if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {                $str = "rmdir /s/q " . $dir;            } else {                $str = "rm -Rf " . $dir;            }            exec($str);        }    }}
 |