Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
迎點擊右上角關(guān)注小編,除了分享技術(shù)文章之外還有很多福利,私信學(xué)習(xí)資料可以領(lǐng)取包括不限于Python實戰(zhàn)演練、PDF電子文檔、面試集錦、學(xué)習(xí)資料等。
將圖片的每個像素用文字代替,最后生成一個HTML文檔,在瀏覽器中可以顯示出圖像,只不過圖像全是由文字組成的。
實現(xiàn)這樣的效果并不復(fù)雜,只不過是用標(biāo)簽代替像素而已,接下來我會演示如何用 PIL/Pillow 庫去實現(xiàn)這樣的效果。
PIL(Python Imaging Library) 是 Python 平臺的圖像處理標(biāo)準(zhǔn)庫。不過 PIL 暫不支持 Python3,可以用 Pillow 代替,API是相同的。
如果你安裝了 pip 的話可以直接輸入 pip install PIL 命令安裝 Pillow。
或者在 PyCharm 中打開 [File] >> [settings] >> [project github] >> [project interpreter] 添加標(biāo)準(zhǔn)庫:
圖片處理過程
圖片轉(zhuǎn)換成網(wǎng)頁的過程,可以分成五個步驟。首先要選擇一個合適的HTML模板,控制好字體的大小和字符間的間距。
然后通過 Python 的 網(wǎng)絡(luò)訪問模塊,根據(jù)URL獲取圖片。接著使用 PIL 模塊載入二進制圖片,將圖片壓縮到合適的尺寸。
遍歷圖片的每一個像素,得到該像素的顏色值,應(yīng)用到HTML的標(biāo)簽上。最后把字符串信息輸出到文件中,生成HTML文檔。
定制模板
大括號代表一個占位符,最后會被替換成實際內(nèi)容,雙大括號中的內(nèi)容則不會被替換。
獲取圖片
通過 URL 得到 byte 數(shù)組形式的圖片。
from urllib import request url = 'https://pic.cnblogs.com/avatar/875028/20160405220401.png' binary = request.urlopen(url).read()
處理圖片
byte 類型的 圖片需要通過 BytesIO 轉(zhuǎn)換為 string 類型,才能被 PIL 處理。
from PIL import Image from io import BytesIO img = Image.open(BytesIO(binary)) img.thumbnail((100, 100)) # 圖片壓縮
生成HTML
使用<font>標(biāo)簽包裹文字,并根據(jù)相應(yīng)像素的RGB值,設(shè)置<font>標(biāo)簽的color屬性。
piexl = img.load() # 獲取像素信息 width, height = img.size # 獲取圖像尺寸 body, word = '', '博客園' font = '<font color="{color}">{word}</font>' for y in range(height): for x in range(width): r, g, b = piexl[x, y] # 獲取像素RGB值 body += font.format( color='#{:02x}{:02x}{:02x}'.format(r, g, b), word=word[((y * width + x) % len(word))] ) body += '\n<br />\n'
導(dǎo)出網(wǎng)頁
向HTML模板中填充處理完成的數(shù)據(jù),使用文件流將字符串以utf8格式輸出到文檔。
html = TEMPLATE.format(title=word, body=body) fo = open('index.html', 'w', encoding='utf8') fo.write(html) fo.close()
img2html
wo把上面五個步驟封裝了起來,這樣一來就可以很方便的調(diào)用了。
from io import BytesIO from PIL import Image from PIL import ImageFilter from urllib import request TEMPLATE = ''' <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{title}</title> <style> body {{ line-height: 1em; letter-spacing: 0; font-size: 0.6rem; background: black; text-align: center; min-width: {size}em; }} </style> </head> <body> {body} </body> </html> ''' class Converter(object): def __init__(self, word='田', size=100): self.word, self.size = word, size self.font = '<font color="{color}">{word}</font>' # 讀取url內(nèi)容 def __network(self, url): return request.urlopen(url).read() # 處理圖片信息 def __handle(self, binary): img = Image.open(BytesIO(binary)) # 打開制圖片 img.thumbnail((self.size, self.size)) # 壓縮圖片 img.filter(ImageFilter.DETAIL) # 圖片增強 return img # 分析圖片像素 def __analysis(self, img): body = '' piexls = img.load() width, height = img.size for y in range(height): for x in range(width): r, g, b = piexls[x, y] body += self.font.format( color='#{:02x}{:02x}{:02x}'.format(r, g, b), word=self.word[((y * width + x) % len(self.word))] ) body += '\n<br />\n' return body # 寫入文件內(nèi)容 def __writefile(self, file, str): fo = open(file, 'w', encoding='utf8') try: fo.write(str) except IOError: raise Exception finally: fo.close() # 生成html文檔 def buildDOC(self, url, output): try: binary = self.__network(url) img = self.__handle(binary) html = TEMPLATE.format( title=self.word, body=self.__analysis(img), size=self.size ) # 向模板中填充數(shù)據(jù) self.__writefile(output, html) except Exception as err: print('Error:', err) return False else: print('Successful!') return True
導(dǎo)入 img2html.Converter,調(diào)用 buildDOC(url, out) 方法
程序會在當(dāng)前目錄生成 index.html 文件,需要用瀏覽器打開后才可以看到效果。
from img2html import Converter conv = Converter('卷福', 120) url = 'http://www.sznews.com/ent/images/attachement/jpg/site3/20140215/001e4f9d7bf91469078115.jpg' out = 'index.html' conv.buildDOC(url, out)
維網(wǎng)和其它網(wǎng)絡(luò)類型最大的區(qū)別就是它在網(wǎng)頁上可呈現(xiàn)豐富多彩的色彩和圖像,還可以播放音頻、視頻,及把圖像作為鏈接使用。
網(wǎng)絡(luò)上流行的圖片格式主要有jpg、jpeg、png、gif等,以下是這幾種格式的介紹。
1、gif格式
gif采用LZW壓縮,是以壓縮相同顏色色塊來減少圖像大小。由于LZW壓縮不會造成任何品質(zhì)的損失,且壓縮率高,支持動畫效果,很適合互聯(lián)網(wǎng)平臺,但是它只支持256種顏色。
2、jpg或jpeg格式
以JPEG有損壓縮圖片,通常用來保存超過256色的圖片格式。JPEG壓縮過程會對一些圖像數(shù)據(jù)造成損失,這部分損失不影響圖片顯示,一般人眼是看不出來差異的。損失數(shù)據(jù)越多,圖片就越不清晰。
3、png格式
png是一種非破壞性的網(wǎng)頁圖像文件格式,它以最小的方式壓縮圖片且不造成圖片數(shù)據(jù)損失。它不僅支持像gif大部分優(yōu)點,還支持48 bit的色彩,跨平臺的圖像亮度控制,更多層的透明度設(shè)置。
網(wǎng)頁中通過<img>標(biāo)簽插入圖片,語法如下:
<img src="圖片路徑" alt="替換文本" />
具體示例:
<!DOCTYPE HTML>
<html>
<body>
<p>
一幅圖像:
<img src="/i/eg_mouse.jpg" width="128" height="128" />
</p>
<p>
一幅動畫圖像:
<img src="/i/eg_cute.gif" width="50" height="50" />
</p>
<p>請注意,插入動畫圖像的語法與插入普通圖像的語法沒有區(qū)別。</p>
</body>
</html>
效果如下:
替換文本屬性(Alt)
alt 屬性用來為圖像定義一串預(yù)備的可替換的文本。
<img src="boat.gif" alt="Big Boat">
當(dāng)瀏覽器無法載入圖像時,替換文本屬性可告訴讀者他們失去的信息。此時,瀏覽器將顯示這個替代性的文本而不是圖像。為頁面上的圖像都加上替換文本屬性是個好習(xí)慣,這樣有助于更好地顯示信息,并且對于那些使用純文本瀏覽器的人來說是非常有用的。
圖像寬度和高度屬性
如下代碼,在網(wǎng)頁中插入一個寬度和高度都是300像素的圖片。
<img src="/i/ct_netscape.jpg" width="300px" height="300px" />
圖片超鏈接
如下代碼,在網(wǎng)頁中對一個圖片進行超鏈接設(shè)置,點擊這張圖片就會跳轉(zhuǎn)到其它頁面。
<a href="頁面路徑"><img src="/i/ct_netscape.jpg" /></a>
除了對整個圖片進行超鏈接設(shè)置外,還可以將圖像劃分成不同區(qū)域進行鏈接設(shè)置,比如一張地圖中給每個省份圖形進行超鏈接。
圖像熱區(qū)鏈接,使用usemap 屬性通過#name指定到名叫name的map元素上,map定義了每個熱區(qū)點擊區(qū)域形狀、大小、坐標(biāo)等。
area標(biāo)簽的 shape 屬性有三種,rect 方形,circle 圓形,poly 多邊形。coords 屬性定義坐標(biāo)點位置,相對于圖片左上角位置。
示例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>W3Cschool(w3cschool.cn)</title>
</head>
<body>
<p>點擊太陽或其他行星,注意變化:</p>
<img src="/statics/images/course/planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap">
<map name="planetmap">
<area shape="rect" coords="0,0,82,126" target="_blank" alt="Sun" href="/statics/images/course/sun.gif">
<area shape="circle" coords="90,58,3" target="_blank" alt="Mercury" href="/statics/images/course/merglobe.gif">
<area shape="circle" coords="124,58,8" target="_blank" alt="Venus" href="/statics/images/course/venglobe.gif">
</map>
</body>
</html>
效果可參考 https://www.w3cschool.cn/html5/html5-img.html 這里。
可以看到鼠標(biāo)在圖片上點擊小行星會打開對應(yīng)的圖片。
到此網(wǎng)頁中使用圖片已經(jīng)大體介紹了,自己親手寫下,會加深印象,感謝關(guān)注。
上篇:前端入門——html 超鏈接
下篇:前端入門——html 如何在網(wǎng)頁中使用視頻音頻
個過程用到了畫布(canvas)來幫忙完成
過程: 選擇圖片文件 > 準(zhǔn)備畫布 > 按需壓縮圖片并繪制在畫布上 > 生成Base64 > 完成.
先上效果圖
詳細過程如下:
準(zhǔn)備一個簡潔的HTML文件, 代碼如下
用一個file dom來選擇圖片文件
<!DOCTYPE html>
<html lang="zh-CN">
<script type="text/javascript" src="../js/jquery.min.js"></script>
<body>
<input name="file" id="thumbnail" type="file" onchange="previewPic(this)"
accept="image/x-png, image/jpg, image/jpeg, image/gif" />
</body>
</html>
為了方便后面的代碼操作, 引用了JQuery
然后準(zhǔn)備2個容器, 一個放預(yù)覽圖; 另一個放Base64內(nèi)容
<div>下面這個Div用來預(yù)覽圖片</div>
<div id="showpic" style="padding:7px;"></div>
<div>下面這個Div用來存放Base64內(nèi)容</div>
<div id="picb64"></div>
接下來是靈魂:JS代碼
function previewPic(tis) {
var fileObj = tis.files[0]; //獲取圖片文件對象
if (undefined == fileObj) { console.log("未選擇待上傳的文件"); return; }
var picid = "imgComp";
$("<img>", {
id: picid,
}).appendTo($("#showpic")); //先生成IMG的DOM,以防順序亂掉
genCompPic(picid, fileObj);
}
function genCompPic(picid, fileObj) {
var ready = new FileReader();
/*開始讀取指定的Blob對象或File對象中的內(nèi)容. 當(dāng)讀取操作完成時,readyState屬性的值會成為DONE,如果設(shè)置了onloadend事件處理程序,則調(diào)用之.同時,result屬性中將包含一個data: URL格式的字符串以表示所讀取文件的內(nèi)容.*/
ready.readAsDataURL(fileObj);
ready.onload = function () {
canvasDataURL(this.result, { width: 200 }, function (base64Codes) {
$("#"+ picid).attr("src", base64Codes); //在IMG DOM中顯示圖片預(yù)覽
$("#picb64").html(base64Codes); //得到Base64結(jié)果,填充到Div中顯示
})
}
}
//利用canvas生成壓縮后的圖片
function canvasDataURL(path, obj, callback) {
var img = new Image();
img.src = path;
img.onload = function () {
var w = obj.width;
var h = obj.width / (this.width/ this.height); //按比例壓縮,計算出等比例高
var canvas = document.createElement('canvas'); //生成canvas
var ctx = canvas.getContext('2d');
// 創(chuàng)建屬性節(jié)點
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw); //設(shè)置圖片寬
canvas.setAttributeNode(anh); //設(shè)置圖片高
ctx.drawImage(this, 0, 0, w, h); //繪制圖片
var quality = 1; // 圖片質(zhì)量為0.1~1, quality值越小,所繪制出的圖像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality); //利用canvas生成Base64
callback(base64); // 回調(diào)函數(shù)返回base64的值
}
}
雖然有點長, 不過關(guān)鍵位置都寫上注釋了, 大家可以參考使用
如果不想壓縮圖片, 在canvasDataURL方法里可以把設(shè)置寬和高的代碼換成原圖參數(shù)即可
完整代碼
<!DOCTYPE html>
<html lang="zh-CN">
<script type="text/javascript" src="../js/jquery.min.js"></script>
<style>
#picb64{width: 95%;height: 300px;overflow-wrap: break-word;overflow: auto;margin: auto;background-color: #676767;border-radius: 10px;}
</style>
<body>
<input name="file" id="thumbnail" type="file" onchange="previewPic(this)"
accept="image/x-png, image/jpg, image/jpeg, image/gif" />
<div>下面這個Div用來預(yù)覽圖片</div>
<div id="showpic" style="padding:7px;"></div>
<div>下面這個Div用來存放Base64內(nèi)容</div>
<div id="picb64"></div>
<script>
function previewPic(tis) {
var fileObj = tis.files[0]; //獲取圖片文件對象
if (undefined == fileObj) { console.log("未選擇待上傳的文件"); return; }
var picid = "imgComp";
$("<img>", {
id: picid,
}).appendTo($("#showpic")); //先生成IMG的DOM,以防順序亂掉
genCompPic(picid, fileObj);
}
function genCompPic(picid, fileObj) {
var ready = new FileReader();
/*開始讀取指定的Blob對象或File對象中的內(nèi)容. 當(dāng)讀取操作完成時,readyState屬性的值會成為DONE,如果設(shè)置了onloadend事件處理程序,則調(diào)用之.同時,result屬性中將包含一個data: URL格式的字符串以表示所讀取文件的內(nèi)容.*/
ready.readAsDataURL(fileObj);
ready.onload = function () {
canvasDataURL(this.result, { width: 200 }, function (base64Codes) {
$("#"+ picid).attr("src", base64Codes); //在IMG DOM中顯示圖片預(yù)覽
$("#picb64").html(base64Codes); //得到Base64結(jié)果,填充到Div中顯示
})
}
}
//利用canvas生成壓縮后的圖片
function canvasDataURL(path, obj, callback) {
var img = new Image();
img.src = path;
img.onload = function () {
var w = obj.width;
var h = obj.width / (this.width/ this.height); //按比例壓縮,計算出等比例高
var canvas = document.createElement('canvas'); //生成canvas
var ctx = canvas.getContext('2d');
// 創(chuàng)建屬性節(jié)點
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw); //設(shè)置圖片寬
canvas.setAttributeNode(anh); //設(shè)置圖片高
ctx.drawImage(this, 0, 0, w, h); //繪制圖片
var quality = 0.8; // 圖片質(zhì)量為0.1~1, quality值越小,所繪制出的圖像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality); //利用canvas生成Base64
callback(base64); // 回調(diào)函數(shù)返回base64的值
}
}
</script>
</body>
</html>
擴展應(yīng)用: 可以利用壓縮后再上傳來節(jié)省帶寬
本期分享就醬紫, 下期再見[看]
復(fù)雜的問題簡單化
每次只關(guān)注一個知識點
對技術(shù)有興趣的小伙伴可以關(guān)注我, 以后會經(jīng)常分享各種奇奇怪怪又實用的技術(shù)知識
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。