首页 > 代码库 > 「脑洞」图片转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+‘.html‘145 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 += ‘,‘ + ‘\n‘165 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 + ‘.html‘182 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 += ‘,‘ + ‘\n‘221 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 = ‘100‘229 elif (i == 0):230 pc = ‘0‘231 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(支持动画)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。