使用PHP+JavaScript将HTML页面转换为图片的实例分享


Posted in Javascript onApril 18, 2016

1,准备要素

1)替换字体的js文件

js代码:

function com_stewartspeak_replacement() {
/*
  Dynamic Heading Generator
  By Stewart Rosenberger
  http://www.stewartspeak.com/headings/
 
  This script searches through a web page for specific or general elements
  and replaces them with dynamically generated images, in conjunction with
  a server-side script.
*/

replaceSelector("h1","dynatext/heading.php",true);//前两个参数需要修改
var testURL = "dynatext/loading.gif" ;//修改为对应的图片路径
 
var doNotPrintImages = false;
var printerCSS = "replacement-print.css";
 
var hideFlicker = false;
var hideFlickerCSS = "replacement-screen.css";
var hideFlickerTimeout = 100;//这里可以做相应的修改

/* ---------------------------------------------------------------------------
  For basic usage, you should not need to edit anything below this comment.
  If you need to further customize this script's abilities, make sure
  you're familiar with Javascript. And grab a soda or something.
*/
 
var items;
var imageLoaded = false;
var documentLoaded = false;
 
function replaceSelector(selector,url,wordwrap)
{
  if(typeof items == "undefined")
    items = new Array();
 
  items[items.length] = {selector: selector, url: url, wordwrap: wordwrap};
}
 
if(hideFlicker)
{    
  document.write('<link id="hide-flicker" rel="stylesheet" media="screen" href="' + hideFlickerCSS + '" />');    
  window.flickerCheck = function()
  {
    if(!imageLoaded)
      setStyleSheetState('hide-flicker',false);
  };
  setTimeout('window.flickerCheck();',hideFlickerTimeout)
}
 
if(doNotPrintImages)
  document.write('<link id="print-text" rel="stylesheet" media="print" href="' + printerCSS + '" />');
 
var test = new Image();
test.onload = function() { imageLoaded = true; if(documentLoaded) replacement(); };
test.src = testURL + "?date=" + (new Date()).getTime();
 
addLoadHandler(function(){ documentLoaded = true; if(imageLoaded) replacement(); });
 
 
function documentLoad()
{
  documentLoaded = true;
  if(imageLoaded)
    replacement();
}
 
function replacement()
{
  for(var i=0;i<items.length;i++)
  {
    var elements = getElementsBySelector(items[i].selector);
    if(elements.length > 0) for(var j=0;j<elements.length;j++)
    {
      if(!elements[j])
        continue ;
     
      var text = extractText(elements[j]);
      while(elements[j].hasChildNodes())
        elements[j].removeChild(elements[j].firstChild);
 
      var tokens = items[i].wordwrap ? text.split(' ') : [text] ;
      for(var k=0;k<tokens.length;k++)
      {
        var url = items[i].url + "?text="+escape(tokens[k]+' ')+"&selector="+escape(items[i].selector);
        var image = document.createElement("img");
        image.className = "replacement";
        image.alt = tokens[k] ;
        image.src = url;
        elements[j].appendChild(image);
      }
 
      if(doNotPrintImages)
      {
        var span = document.createElement("span");
        span.style.display = 'none';
        span.className = "print-text";
        span.appendChild(document.createTextNode(text));
        elements[j].appendChild(span);
      }
    }
  }
 
  if(hideFlicker)
    setStyleSheetState('hide-flicker',false);
}
 
function addLoadHandler(handler)
{
  if(window.addEventListener)
  {
    window.addEventListener("load",handler,false);
  }
  else if(window.attachEvent)
  {
    window.attachEvent("onload",handler);
  }
  else if(window.onload)
  {
    var oldHandler = window.onload;
    window.onload = function piggyback()
    {
      oldHandler();
      handler();
    };
  }
  else
  {
    window.onload = handler;
  }
}
 
function setStyleSheetState(id,enabled) 
{
  var sheet = document.getElementById(id);
  if(sheet)
    sheet.disabled = (!enabled);
}
 
function extractText(element)
{
  if(typeof element == "string")
    return element;
  else if(typeof element == "undefined")
    return element;
  else if(element.innerText)
    return element.innerText;
 
  var text = "";
  var kids = element.childNodes;
  for(var i=0;i<kids.length;i++)
  {
    if(kids[i].nodeType == 1)
    text += extractText(kids[i]);
    else if(kids[i].nodeType == 3)
    text += kids[i].nodeValue;
  }
 
  return text;
}
 
/*
  Finds elements on page that match a given CSS selector rule. Some
  complicated rules are not compatible.
  Based on Simon Willison's excellent "getElementsBySelector" function.
  Original code (with comments and description):
    http://simon.incutio.com/archive/2003/03/25/getElementsBySelector
*/
function getElementsBySelector(selector)
{
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for(var i=0;i<tokens.length;i++)
  {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
    if(token.indexOf('#') > -1)
    {
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if(tagName && element.nodeName.toLowerCase() != tagName)
        return new Array();
      currentContext = new Array(element);
      continue;
    }
 
    if(token.indexOf('.') > -1)
    {
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if(!tagName)
        tagName = '*';
 
      var found = new Array;
      var foundCount = 0;
      for(var h=0;h<currentContext.length;h++)
      {
        var elements;
        if(tagName == '*')
          elements = currentContext[h].all ? currentContext[h].all : currentContext[h].getElementsByTagName('*');
        else
          elements = currentContext[h].getElementsByTagName(tagName);
 
        for(var j=0;j<elements.length;j++)
          found[foundCount++] = elements[j];
      }
 
      currentContext = new Array;
      var currentContextIndex = 0;
      for(var k=0;k<found.length;k++)
      {
        if(found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b')))
          currentContext[currentContextIndex++] = found[k];
      }
 
      continue;
    }
 
    if(token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/))
    {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if(!tagName)
        tagName = '*';
 
      var found = new Array;
      var foundCount = 0;
      for(var h=0;h<currentContext.length;h++)
      {
        var elements;
        if(tagName == '*')
          elements = currentContext[h].all ? currentContext[h].all : currentContext[h].getElementsByTagName('*');
        else
          elements = currentContext[h].getElementsByTagName(tagName);
 
        for(var j=0;j<elements.length;j++)
          found[foundCount++] = elements[j];
      }
 
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction;
      switch(attrOperator)
      {
        case '=':
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~':
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|':
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^':
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$':
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*':
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
 
      currentContext = new Array;
      var currentContextIndex = 0;
      for(var k=0;k<found.length;k++)
      {
        if(checkFunction(found[k]))
          currentContext[currentContextIndex++] = found[k];
      }
 
      continue;
    }
 
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for(var h=0;h<currentContext.length;h++)
    {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for(var j=0;j<elements.length; j++)
        found[foundCount++] = elements[j];
    }
 
    currentContext = found;
  }
 
  return currentContext;
}
 
 
}// end of scope, execute code
if(document.createElement && document.getElementsByTagName && !navigator.userAgent.match(/opera\/?6/i))
  com_stewartspeak_replacement();

2)生成图片的php文件

<?php
/*
  Dynamic Heading Generator
  By Stewart Rosenberger
  http://www.stewartspeak.com/headings/  
 
  This script generates PNG images of text, written in
  the font/size that you specify. These PNG images are passed
  back to the browser. Optionally, they can be cached for later use. 
  If a cached image is found, a new image will not be generated,
  and the existing copy will be sent to the browser.
 
  Additional documentation on PHP's image handling capabilities can
  be found at http://www.php.net/image/  
*/

$font_file = 'trebuc.ttf' ;//可以做相应的xiuga
$font_size = 23 ;//可以做相应的修改
$font_color = '#000000' ;
$background_color = '#ffffff' ;
$transparent_background = true ;
$cache_images = true ;
$cache_folder = 'cache' ;

/*
 ---------------------------------------------------------------------------
  For basic usage, you should not need to edit anything below this comment.
  If you need to further customize this script's abilities, make sure you
  are familiar with PHP and its image handling capabilities.
 ---------------------------------------------------------------------------
*/
 
$mime_type = 'image/png' ;
$extension = '.png' ;
$send_buffer_size = 4096 ;
 
// check for GD support
if(!function_exists('ImageCreate'))
  fatal_error('Error: Server does not support PHP image generation') ;
 
// clean up text
if(empty($_GET['text']))
  fatal_error('Error: No text specified.') ;
   
$text = $_GET['text'] ;
if(get_magic_quotes_gpc())
  $text = stripslashes($text) ;
$text = javascript_to_html($text) ;
 
// look for cached copy, send if it exists
$hash = md5(basename($font_file) . $font_size . $font_color .
      $background_color . $transparent_background . $text) ;
$cache_filename = $cache_folder . '/' . $hash . $extension ;
if($cache_images && ($file = @fopen($cache_filename,'rb')))
{
  header('Content-type: ' . $mime_type) ;
  while(!feof($file))
    print(($buffer = fread($file,$send_buffer_size))) ;
  fclose($file) ;
  exit ;
}
 
// check font availability
$font_found = is_readable($font_file) ;
if(!$font_found)
{
  fatal_error('Error: The server is missing the specified font.') ;
}
 
// create image
$background_rgb = hex_to_rgb($background_color) ;
$font_rgb = hex_to_rgb($font_color) ;
$dip = get_dip($font_file,$font_size) ;
$box = @ImageTTFBBox($font_size,0,$font_file,$text) ;
$image = @ImageCreate(abs($box[2]-$box[0]),abs($box[5]-$dip)) ;
if(!$image || !$box)
{
  fatal_error('Error: The server could not create this heading image.') ;
}
 
// allocate colors and draw text
$background_color = @ImageColorAllocate($image,$background_rgb['red'],
  $background_rgb['green'],$background_rgb['blue']) ;
$font_color = ImageColorAllocate($image,$font_rgb['red'],
  $font_rgb['green'],$font_rgb['blue']) ;  
ImageTTFText($image,$font_size,0,-$box[0],abs($box[5]-$box[3])-$box[1],
  $font_color,$font_file,$text) ;
 
// set transparency
if($transparent_background)
  ImageColorTransparent($image,$background_color) ;
 
header('Content-type: ' . $mime_type) ;
ImagePNG($image) ;
 
// save copy of image for cache
if($cache_images)
{
  @ImagePNG($image,$cache_filename) ;
}
 
ImageDestroy($image) ;
exit ;
 
 
/*
  try to determine the "dip" (pixels dropped below baseline) of this
  font for this size.
*/
function get_dip($font,$size)
{
  $test_chars = 'abcdefghijklmnopqrstuvwxyz' .
         'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
         '1234567890' .
         '!@#$%^&*()\'"\\/;.,`~<>[]{}-+_-=' ;
  $box = @ImageTTFBBox($size,0,$font,$test_chars) ;
  return $box[3] ;
}
 
 
/*
  attempt to create an image containing the error message given. 
  if this works, the image is sent to the browser. if not, an error
  is logged, and passed back to the browser as a 500 code instead.
*/
function fatal_error($message)
{
  // send an image
  if(function_exists('ImageCreate'))
  {
    $width = ImageFontWidth(5) * strlen($message) + 10 ;
    $height = ImageFontHeight(5) + 10 ;
    if($image = ImageCreate($width,$height))
    {
      $background = ImageColorAllocate($image,255,255,255) ;
      $text_color = ImageColorAllocate($image,0,0,0) ;
      ImageString($image,5,5,5,$message,$text_color) ;  
      header('Content-type: image/png') ;
      ImagePNG($image) ;
      ImageDestroy($image) ;
      exit ;
    }
  }
 
  // send 500 code
  header("HTTP/1.0 500 Internal Server Error") ;
  print($message) ;
  exit ;
}
 
 
/* 
  decode an HTML hex-code into an array of R,G, and B values.
  accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff 
*/  
function hex_to_rgb($hex)
{
  // remove '#'
  if(substr($hex,0,1) == '#')
    $hex = substr($hex,1) ;
 
  // expand short form ('fff') color
  if(strlen($hex) == 3)
  {
    $hex = substr($hex,0,1) . substr($hex,0,1) .
        substr($hex,1,1) . substr($hex,1,1) .
        substr($hex,2,1) . substr($hex,2,1) ;
  }
 
  if(strlen($hex) != 6)
    fatal_error('Error: Invalid color "'.$hex.'"') ;
 
  // convert
  $rgb['red'] = hexdec(substr($hex,0,2)) ;
  $rgb['green'] = hexdec(substr($hex,2,2)) ;
  $rgb['blue'] = hexdec(substr($hex,4,2)) ;
 
  return $rgb ;
}
 
 
/*
  convert embedded, javascript unicode characters into embedded HTML
  entities. (e.g. '%u2018' => '‘'). returns the converted string.
*/
function javascript_to_html($text)
{
  $matches = null ;
  preg_match_all('/%u([0-9A-F]{4})/i',$text,$matches) ;
  if(!empty($matches)) for($i=0;$i<sizeof($matches[0]);$i++)
    $text = str_replace($matches[0][$i],
              '&#'.hexdec($matches[1][$i]).';',$text) ;
 
  return $text ;
}
 
?>

3)需要的字体

这里将需要的自己放在与js和php文件同在的一个目录下(也可以修改,但是对应文件也要修改)

4)PHP的GD2库

2,实现的html代码

<?php
//load the popup utils library
//require_once 'include/popup_utils.inc.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
  <head>
    <title>
      Professional Search Engine Optimization with PHP: Table of Contents
    </title>
    <script type="text/javascript" language="javascript" src="dynatext/replacement.js"></script>
  </head>
  <body onload="window.resizeTo(800,600);" onresize='setTimeout("window.resizeTo(800,600);", 100)'>
    <h1>
      Professional Search Engine Optimization with PHP: Table of Contents
    </h1>
    <?php
      //display popup navigation only when visitor comes from a SERP
      // display_navigation();
      //display_popup_navigation();
    ?>
    <ol>
      <li>You: Programmer and Search Engine Marketer</li>
      <li>A Primer in Basic SEO</li>
      <li>Provocative SE-Friendly URLs</li>
      <li>Content Relocation and HTTP Status Codes</li>
      <li>Duplicate Content</li>
      <li>SE-Friendly HTML and JavaScript</li>
      <li>Web Syndication and Social Bookmarking</li>
      <li>Black Hat SEO</li>
      <li>Sitemaps</li>
      <li>Link Bait</li>
      <li>IP Cloaking, Geo-Targeting, and IP Delivery</li>
      <li>Foreign Language SEO</li>
      <li>Coping with Technical Issues</li>
      <li>Site Clinic: So You Have a Web Site?</li>
      <li>WordPress: Creating a SE-Friendly Weblog?</li>
      <li>Introduction to Regular Expression</li>
    </ol>
  </body>
</html>

3,使用效果前后对比
使用前

使用PHP+JavaScript将HTML页面转换为图片的实例分享

使用后

使用PHP+JavaScript将HTML页面转换为图片的实例分享

Javascript 相关文章推荐
jQuery中与toggleClass等价的程序段 以及未来学习的方向
Mar 18 Javascript
jQuery中append、insertBefore、after与insertAfter的简单用法与注意事项
Apr 04 Javascript
自己做的模拟模态对话框实现代码
May 23 Javascript
浅谈Javascript中深复制
Dec 01 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
jQuery图片切换动画特效
Nov 02 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
Dec 18 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
Mar 04 Javascript
基于Vue的延迟加载插件vue-view-lazy
May 21 Javascript
详解Vue webapp项目通过HBulider打包原生APP(vue+webpack+HBulider)
Feb 02 Javascript
VUE注册全局组件和局部组件过程解析
Oct 10 Javascript
国内常用的js类库大全(CDN公共库)
Jun 24 Javascript
简单讲解jQuery中的子元素过滤选择器
Apr 18 #Javascript
举例讲解jQuery中可见性过滤选择器的使用
Apr 18 #Javascript
html5+javascript实现简单上传的注意细节
Apr 18 #Javascript
jQuery的内容过滤选择器学习教程
Apr 18 #Javascript
原生JS和jQuery版实现文件上传功能
Apr 18 #Javascript
基于Bootstrap实现Material Design风格表单插件 附源码下载
Apr 18 #Javascript
jQuery 如何给Carousel插件添加新的功能
Apr 18 #Javascript
You might like
mysql中存储过程、函数的一些问题
2007/02/14 PHP
如何在smarty中增加类似foreach的功能自动加载数据
2013/06/26 PHP
PHP实现批量上传单个文件
2015/12/29 PHP
gearman中任务的优先级和返回状态实例分析
2020/02/27 PHP
Javascript 布尔型分析
2008/12/22 Javascript
javascript 页面只自动刷新一次
2009/07/10 Javascript
javascript两段代码,两个小技巧
2010/02/04 Javascript
表单元素的submit()方法和onsubmit事件应用概述
2013/02/01 Javascript
js onload处理html页面加载之后的事件
2013/10/30 Javascript
深入分析javascript中的错误处理机制
2016/07/17 Javascript
jQuery搜索框效果实现代码(百度关键词联想)
2021/02/25 Javascript
JavaScript实现DOM对象选择器
2016/09/24 Javascript
Web制作验证码功能实例代码
2017/06/19 Javascript
Vue组件教程之Toast(Vue.extend 方式)详解
2019/01/27 Javascript
Vue移动端实现图片上传及超过1M压缩上传
2019/12/23 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
2020/11/19 Javascript
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
[01:00:53]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Secret
2018/03/30 DOTA
windows系统中python使用rar命令压缩多个文件夹示例
2014/05/06 Python
python妹子图简单爬虫实例
2015/07/07 Python
Python中.py文件打包成exe可执行文件详解
2017/03/22 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
python中aioysql(异步操作MySQL)的方法
2019/04/11 Python
Django ORM 查询管理器源码解析
2019/08/05 Python
Python 70行代码实现简单算式计算器解析
2019/08/30 Python
深入了解python列表(LIST)
2020/06/08 Python
Python tkinter实现日期选择器
2021/02/22 Python
德国家具购物网站:Möbel Höffner
2019/08/26 全球购物
C/C++ 笔试、面试题目大汇总
2015/11/21 面试题
申报职称专业技术个人的自我评价
2013/12/12 职场文书
办公室班子四风问题对照检查材料
2014/10/04 职场文书
工作失职造成投诉的检讨书范文
2014/10/05 职场文书
旗帜观后感
2015/06/08 职场文书
2019垃圾分类宣传口号汇总
2019/08/16 职场文书
详解MySQL连接挂死的原因
2021/05/18 MySQL
JavaGUI模仿QQ聊天功能完整版
2021/07/04 Java/Android