首页 > 代码库 > 「脑洞」图片转HTML(支持动画)

「脑洞」图片转HTML(支持动画)

也许是受到很久以前看到的这玩意儿的原因:The Shapes of CSS

现在开脑洞写了个自动转换,顺便支持了动画……嗯,纯 CSS (:з」∠)

主要步骤就是用 Python 读图片,然后把像素全转写成 CSS 的 box-shadow ,最后构建一个完整的 HTML 文件输出。

然后用浏览器打开生成的 HTML 文件,就直接看到图片了,如果输入是一个文件夹的话,就以文件夹里面的图片为帧生成一个带动画的 HTML。

最新的版本就在这儿了: img2html

  1 #!/usr/bin/env python3  2 # -*- coding: utf-8 -*-  3   4 ## @package img2html  5 #  Usage        : img2html.py file1|dir1 [file2|dir2 ...]  6 #  Description  : generate html uses box-shadow to show picture  7 #                 or a html to show your image sequence in a folder as css animation  8 #  Dependencies : Python Image Library, Python 3  9 #  Note         : Take care of the Super-High-Energy output ( >﹏<。) 10 #  Date         : 2014-12-19 11 #  Author       : frantic1048 12  13  14 import sys 15 import os 16 from PIL import Image 17 from string import Template 18  19 class UnknownColorMode(Exception): pass 20  21 ## @var tHTML template for constructing entire html document 22 tHTML = Template(‘‘‘ 23 <!doctype html> 24 <html lang="en"> 25 <head> 26   <meta charset="UTF-8"> 27   <title>~ ${name} ~</title> 28 </head> 29 <body> 30   <style type="text/css">${css}</style> 31   <div id="image_kun"></div> 32 </body> 33 </html>‘‘‘) 34  35 ## @var tCSSStatic template for constructing static image‘s css code 36 tCSSStatic = Template(‘‘‘ 37 @charset "utf-8"; 38 body{ 39   display:flex; 40   justify-content:center; 41   align-items:center; 42 } 43 #image_kun{ 44   height: ${height}px; 45   width: ${width}px; 46   position:relative; 47 } 48 #image_kun::after{ 49   position:absolute; 50   height:1px; 51   width:1px; 52   background:${firstPixel}; 53   margin:0; 54   padding:0; 55   content:"\\200B";/*ZWS*/ 56   box-shadow: 57   ${boxshadow}; 58 } 59 ‘‘‘) 60  61 ## @var tCSSAnimation template for constructing image sequence‘s css animation code 62 tCSSAnimation = Template(‘‘‘ 63 @charset "utf-8"; 64 body{ 65   display:flex; 66   justify-content:center; 67   align-items:center; 68 } 69 #image_kun{ 70   height: ${height}px; 71   width: ${width}px; 72   position:relative; 73 } 74 #image_kun::after{ 75   position:absolute; 76   height:1px; 77   width:1px; 78   background:transparent; 79   margin:0; 80   padding:0; 81   content:"\\200B";/*ZWS*/ 82   animation:ayaya ${animationLength} step-end infinite alternate; 83 } 84 ${animationKeyFrames} 85   ‘‘‘) 86  87 ## @var tCSSKeyframes template entire CSS keyframes rule 88 tCSSKeyframes = Template(@keyframes ayaya {${keyframes}}) 89  90 ## @var tCSSKeyframe template for a single CSS keyframe 91 tCSSKeyframe = Template(${percentage}% {${keyframeRule}}\n) 92  93 ## @var tCSSKeyframeRule template for a single CSS keyframe inner rule 94 tCSSKeyframeRule = Template(background:${firstPixel};box-shadow:${boxshadow};) 95  96 ## ensure no trailiing slash in directory name 97 def toRegularDirName(dirName): 98 if (os.path.split(dirName)[-1] == ‘‘): 99   return os.path.split(dirName)[0]100 else:101   return dirName102 103 ## write str to a file,named as <exportFileName>.html104 def toFile (str,exportFileName):105   with open (exportFileName,w) as html:106 html.write(str)107 108 ## construct HEX Color value for a pixel109 #  @param pixel a RGB mode pixel object to be converted110 #  @return CSS hex format color value111 def toHexColor (pixel):112   return #{0:02x}{1:02x}{2:02x}.format(*pixel[:])113 114 ## construct RGBA Color value for a pixel115 #  @param pixel a RGBA mode pixle object to be comverted116 #  @return CSS rgba format color value117 def toRGBAColor (pixel):118   return rgba({0},{1},{2},{3}).format(*pixel[:])119 120 def toCSSColor (pixel, mode):121   if (mode == RGB):122 return toHexColor(pixel)123   elif (mode == RGBA):124 return toRGBAColor(pixel)125   else:126 raise UnknownColorMode127 128 ## construct single box-shadow param129 #  @param color valid CSS color130 def toBoxShadowParam (x, y, color):131   return format(%spx %spx 0 %s%(x, y, color))132 133 ## process single image file to html134 #  @param fileName input file‘s name135 #  @param export output callback(doc, exportFileName):136 #    doc : generated html string137 #    exportFileName : output filename138 def mipaStatic(fileName,export=‘‘):139   with Image.open(fileName) as im:140 ## what called magic141 boxshadow = ‘‘142 143 ## file name as sysname144 exportFileName = fileName+.html145 title = os.path.split(fileName)[-1]146 147 ## image size148 width, height = im.size[0], im.size[1]149 150 #ensure RGB(A) mode151 if (im.mode != RGBA or im.mode != RGB):152   im.convert(RGB)153 154 firstPixel = toCSSColor(im.getpixel((0,0)), im.mode)155 for y in range(0, height):156   for x in range(0, width):157     color = toCSSColor(im.getpixel((x, y)), im.mode)158     #link magic159     boxshadow += toBoxShadowParam(x, y, color)160 161     #add a spliter if not the end162     if (not (y == height-1 and x == width-1)):163       #keep a ‘\n‘ for text editor ˊ_>ˋ164       boxshadow += , + \n165 166 doc = tHTML.substitute(name = title, css = tCSSStatic.substitute(width = width, height = height, boxshadow = boxshadow, firstPixel=firstPixel))167 if (export==‘‘):168   print(doc)169 else:170   export(doc, exportFileName)171 172 173 ## process a image folder174 #  files in folder will processed to an animated html175 #  process order is filename asend176 #  @param dirName input file‘s name177 #  @param export output callback, call with generated html as a string argument178 def mipaAnimation(dirName,export=‘‘):179   dirName = toRegularDirName(dirName)180   title = os.path.basename(dirName)181   exportFileName = title + .html182 183   files = os.listdir(dirName)184   files.sort()185 186   FPS = 24187   mode = ‘‘188   width, height = 0, 0189   frameCount = 0190   keyframeRules = []191   keyframe = ‘‘192 193   for f in files:194 try:195   with Image.open(os.path.join(dirName, f)) as im:196 197     if (export!=‘‘):print(processing file -->  + f)198 199     frameCount+=1200 201     #ensure RGB(A) mode202     if (im.mode != RGBA or im.mode != RGB):203       im.convert(RGB);204 205     #collect animation info206     if (width == 0) : width, height = im.size[0], im.size[1]207     if (mode == ‘‘) : mode = im.mode208 209     firstPixel = toCSSColor(im.getpixel((0,0)), mode)210     boxshadow = ‘‘211     for y in range(0, height):212       for x in range(0, width):213     color = toCSSColor(im.getpixel((x, y)), mode)214     #link magic215     boxshadow += toBoxShadowParam(x, y, color)216 217     #add a spliter if not the end218     if (not (y == height-1 and x == width-1)):219       #keep a ‘\n‘ for text editor ˊ_>ˋ220       boxshadow += , + \n221     keyframeRules.append(tCSSKeyframeRule.substitute(firstPixel=firstPixel,boxshadow=boxshadow))222 except:223   pass224 225   percentUnit= 100/frameCount226   for i in range(0,frameCount):227 if (i == frameCount - 1):228   pc = 100229 elif (i == 0):230   pc = 0231 else:232   pc = str(percentUnit * i)233 keyframe += tCSSKeyframe.substitute(percentage = pc, keyframeRule = keyframeRules[i])234 235   if (export!=‘‘):print(generating document...)236   doc = tHTML.substitute(name = title, css = tCSSAnimation.substitute(animationLength = str((1000 / FPS) * frameCount) + ms,237                                       animationKeyFrames = tCSSKeyframes.substitute(keyframes = keyframe),238                                       height = height,239                                       width = width))240   #output241   if (export==‘‘):242 print(doc)243   else:244 print(Start exporting...)245 export(doc, exportFileName)246 print(Finished exporting !\nenjoy with your magical  + exportFileName +  _(:з」∠)_)247 248 249 for path in sys.argv[1:]:250   if os.path.isfile(path):251 ##export to stdout252 #mipaStatic(path)253 254 ##export to autonamed file255 mipaStatic(path,toFile)256   elif os.path.isdir(path):257 #mipaAnimation(path)258 mipaAnimation(path,toFile)

 

「脑洞」图片转HTML(支持动画)