整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

10行JavaScript代码完成图片的上传预览

击右上方红色按钮关注“web秀”,让你真正秀起来

前言

冬至,希望大家都可以有饺子和汤圆吃,主要是能和自己家人爱人一起吃个饭。

下面进入主题,用原生JS给撸个图片上传,预览的小示例,希望对大家有所帮助。

示例

function fChange() { 
 let file = document.getElementById('file'); 
 // 输出已经选择图片名字 
 console.log(file.value); 
 // 输出已经选择的图片对象 
 console.log(file.files[0]); 
} 
... 
<input type="file" id="file" onchange="fChange()">

10行JavaScript代码完成图片的上传预览

我们怎么把图片对象渲染到页面了?达到可以预览的目的?

// file 转 blob对象 
let bold = window.URL.createObjectURL(file.files[0]); 
console.log('bold==>'+bold); 
 
let boldImg = document.getElementById('bold'); 
boldImg.src = bold; 
 
// file 转 base64 
let base64Img = document.getElementById('base64'); 
var reader = new FileReader(); 
reader.readAsDataURL(file.files[0]); 
reader.onload = function (e) { 
 console.log('base64==>'+this.result); 
 base64Img.src = this.result; 
}

10行JavaScript代码完成图片的上传预览

10行JavaScript代码完成图片的上传预览

这样看blob对象和base64都可以预览图片,但是blob对象仅仅是当次缓存,如果刷新,你重新把之前转的字符串放到src是不可以预览的,当时base64是可以的。所以存库的时候不仅可以图片路径,还可以直接存base64(base64很占用数据库空间,文件越大,base64字符串越大)

优化

下面我们对上面示例做优化,可以上传多张图片并预览,美化界面。

10行JavaScript代码完成图片的上传预览

10行JavaScript代码完成图片的上传预览

<div id="img-pre"> 
</div> 
<div id="add-pic"> 
 <input type="file" id="up-file" onchange="fChange()"> 
</div>

css样式

#add-pic{ 
 width: 100px; 
 height: 100px; 
 background: url('./add-pic.png') 
} 
#add-pic input{ 
 width: 100%; 
 height: 100%; 
 display: none; 
} 
#img-pre:after{ 
 display: block; 
 content: ''; 
 clear: both; 
} 
#img-pre img{ 
 float: left; 
 width: 100px; 
 height: 100px; 
 margin-right: 10px; 
}

javascript

let addPic = document.getElementById('add-pic'), upFile = document.getElementById('up-file'); 
// 监听图片点击,从而触发input file的点击事件 
addPic.addEventListener('click', function(){ 
 upFile.click(); 
}) 
function fChange() { 
 let file = document.getElementById('up-file'); 
 let imgPre = document.getElementById('img-pre'); 
 
 // file 转 blob对象 
 let bold = window.URL.createObjectURL(file.files[0]); 
 
 // 创建img元素,并添加到img-pre元素里 
 var img = document.createElement("img"); 
 img.setAttribute("src", bold); 
 imgPre.appendChild(img); 
}

主要是通过css隐藏掉input file选择文件按钮,然后用+号图片点击事件来触发input file的点击事件,达到能选择图片的目的。

公告

喜欢小编的点击关注,了解更多知识!

源码地址请点击下方“了解更多”

.什么是文本和图像链接!

浏览网页时,会看到一些带下划线的文字。,将光标移到文字上时,光标将变成手形,单击会打开一个网页,这样的链接就是文本链接。

在网页中浏览内容时,若将光标移到图像上,光标会变成手形,单击会打开一个网页,这样的链接就是图像链接。

文本链接

图像链接

2.创建链接的方法!

使用<a>标签可以实现网页超链接,但<a>标签需要定义锚来指定链接目标。锚(anchor)有两种用法,介绍如下:

(1)通过使用href属性,创建指向另外一个文档的链接(或超链接);

(2)通过使用name和id属性,创建一个文档内部的书签(也就是说,可以创建指向文档片段的链接)。

使用href属性的代码格式如下:

<a href="链接地址">创建链接的文本或图片</a>

使用name属性的代码格式如下:

<a name="value">创建链接的文本或图片</a>

name属性用于指定锚(anchor)的名称,可以创建(大型)文档内的书签。

使用id属性的代码格式如下:

<a id="value">创建链接的文本或图片</a>

3.创建网页内的文本链接!

创建网页内的文本链接主要使用href属性来实现,如在网页中做一些知名网站的友情链接,具体操作方法如下。

(1)编写代码如下图所示:

(2)在浏览器中打开文件,预览效果如下所示,可以看到带有超链接的文本呈现浅紫色。

小提示:链接地址前的“http:// ”不可省略,否则会出现错误提示。

4.创建网站内的图像链接!

使用<a>标签为图片添加链接的代码格式如下:

<a href="链接目标l"><img src="图片"/></a>

下面是一个简单的图片链接案例。

(1)编写代码如下图所示:

(2)在浏览器中打开文件,预览效果如下所示。光标放在图片上呈现抓手形,单击后可跳转到指定网页。

浏览器截图


小提示:文件中的图片要和当前网页文件在同一个目录下,链接的网页没有加“http:// ”,默认为当前网页所在目录。

以下网页有102个图标,如何一次性爬取?

http://www.pp3.cn/icon/size/16_16/2011/1128/831.html

试试以下小程序:

import re
import urllib.request
import os
                            #1 抓取网页(网页上有图片地址)
url = 'http://www.pp3.cn/icon/size/qita/2011/1128/758.html'
req = urllib.request.urlopen(url)
buf = req.read()
req.close()
                            #2 获取图片地址
# 下面4句截取url的前半截,如http://www.pp3.cn(一些图片是相对地址)
i = url.find("/",9) 
url0 = url
if i > 0 :
    url0 = url[:i]  
buf = buf.decode('gb2312')              # 有些网页编码是utf-8,要一致
listurl = re.findall(r'img src=.[^\'\"]+\.png',buf)

for i in range(len(listurl)):           # 把字符img src="去掉
    listurl[i]=listurl[i].replace('img src="',"")
    if not re.match("http",listurl[i]): # 如果是相对地址,加上上面提取的基地址
        listurl[i]=url0 + listurl[i]
    print(listurl[i])                   # 将图片地址列表打印一下
    
                            #3 抓取图片并保存到本地
fpath = "D:\\pic2\\"
if not os.path.isdir(fpath):
    os.mkdir(fpath)
i = 0
for url in listurl:
    f=open(fpath + str(i)+'.png','wb')
    req = urllib.request.urlopen(url)
    buf = req.read()
    f.write(buf)
    f.close()
    i+=1

有四个关键点:

1 网页的编码:有的是GB2312,有的是utf-8。

2 有的网站服务器做了反爬虫设置,需要写较复杂的代码来绕过。

3 图片网址正则表达式的设置。如上述的

r'img src=.[^\'\"]+\.png'

图片的HTML的写法:

img src='http//…/picPath/…/.png'
img src='http//…/picPath/…/.jpg'
img src="http//…/picPath/…/.jpg"
img src="picPath/…/.jpg"

要通过适当的正则表达式来构建上述字符串表示规律。

3.1 圆点“.”表示除'\n'以外的任意字符。上述可以表示单引号或双引号,如果没有其它字符,如在引用前还有一个字符,可多写一个圆点.。

3.2 “[^\'\"]+”表示一串除了单引号或双引号以外的任意数量的其它字符。直到遇到“\.png”为止(可能出现贪婪匹配)。“[]”表示列举,“^”表示非,排除后面紧跟的字符;“\”表示转义,转义是指转变原本的含义,单引号和双引号原本是用来界定字符的,用转义符来放弃这个用途,用做普通字符。加号“+”表示一个或多个前面的字符表示。

3.3 "\.png"表示圆点.和图片的类型png。

上面说到贪婪匹配,要设置为非贪婪匹配,用小括号分组加一个问号即可:

reg = r'img src=.([^\'\"]+\.png)?'

如果出现问题,可以相看原网页的图片地址编写格式及规律,简单化处理。

如图片地址都有如下规律,

http://www.pp3.cn/uploads/allimg/111128/1-11112…….png

可将正则表达式简单写为:

http://www.pp3.cn/uploads/allimg/111128/1-11112\S*.png

“/S*”表示任意数量非空白字符。

如果有多个网页,可以将上述代码写成函数形式,循环调用:

import re                     # 正则表达式
import urllib.request         # 从服务器请求返回资源
import os                     # 文件和目录操作
import socket                 # 套接字操作
#socket.setdefaulttimeout(20) # 设置socket层的超时时间为20秒
def gethtml(url):                                               #1 抓取网页html内容
    with urllib.request.urlopen(url) as req:
        buf = req.read()
        return buf
def getImg(buf,codec,fpath,rege):                               #2 从html筛选图片地址到list
# 下面4句截取url的前半截,如http://www.pp3.cn(一些图片是相对地址)
    i = url.find("/",9)
    url0 = url
    if i > 0 :
        url0 = url[:i]
        
    buf = buf.decode(codec)
    listurl = re.findall(reg,buf) #reg是正则表达式
    print("准备下载图片数量:",len(listurl))
    for i in range(len(listurl)):                
        #listurl[i]=listurl[i].replace('img src="',"") # 把字符img src="去掉
        if not re.match("http",listurl[i]):
            listurl[i]=url0 + listurl[i]
        print(listurl[i])
                                                                 #3 抓取图片并保存到本地
    if not os.path.isdir(fpath):
        os.mkdir(fpath)
    i = 0
    '''
    for imgurl in listurl:
        urllib.request.urlretrieve(imgurl,fpath + str(i)+'.jpg')
        i+=1
    '''#下面的操作方式要快一点
    for imgurl in listurl:
        f=open(fpath + str(i)+'.jpg','wb')      # 新建空白图片文件
        req = urllib.request.urlopen(imgurl)    # 获取网页图片文件
        buf = req.read()                        # 读取网站上图片文件内容
        f.write(buf)                            # 将网站上图片内容写入新建的图片文件
        f.close()
        i+=1
# 四处内容需要确认:1 网页url;                   2 网页编码UTF-8或gb2312;
#                   3 图片扩展名jpg或png(两处); 4 保存的文件夹

codec = 'gb2312'
reg = r'img src=.([^\'\"]+\.png)?'
webpages = ['http://www.pp3.cn/icon/size/qita/2011/1128/758.html', # 需提取图片的网址可写到列表内
            'http://www.pp3.cn/icon/size/32_32/2011/1128/768.html'
            ]
i = 0
for url in webpages:
    buf = gethtml(url)
    fpath = "D:\\" + str(i) +"\\"
    print(getImg(buf,codec,fpath,reg))  	 # 函数循环调用
    i+=1
    
url = 'http://culture.ifeng.com/c/7vm9bFrvQpl'
codec = 'utf-8'
buf = gethtml(url)
reg = r'img src=..([^\'\"]+\.jpeg)?'
fpath = 'D:\\A\\'
print(getImg(buf,codec,fpath,reg))  	    	 # 函数单独调用

图片格式不同的较灵活的写法:


import re
import urllib.request
import os
from itertools import islice  # 跳过可迭代对象的开始部分

# fpath = "D:\\pic2\\"
# 分析网页文本、提到图片超链接到list,逐一将list项保存到图片文件
# ① 要注意网页的字符编码,可在网页查看

# ② 要注意网站图片的url格式规律
# ③ 要注意图片的扩展名

# ④ 一次老是抓取不成功,原因是第三张无法打开,后跳过


#"""
# 1 获取网页文本

url = 'http://www.pp3.cn/icon/size/16_16/2011/1128/831.html'
#url = 'http://www.pp3.cn/icon/size/16_16/2011/1128/835.html'
# 1.1 url没加header的写法


req = urllib.request.urlopen(url)
buf = req.read()
req.close()


# 1.2 在urllib中添加headers不同的写法,需要headers是字典或元组
"""
headers = {  # 如有反爬,可添加网页自己的header
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
    }
req  = urllib.request.Request(url=url,headers=headers)
file = urllib.request.urlopen(req)
buf  = file.read()
"""
#2 多网页文本中解析出图片地址
i = url.find("/",9) # 本句及下面三句截取url的前半截
url2 = url
if i > 0 :
    url2 = url[:i]
#buf = buf.decode('UTF-8')
buf = buf.decode('gb2312')
#picType = '.jpg'
#picType = '.jpeg'
picType = '.png'
#picType = '.gif'
#listurl = re.findall(r'http:.[^"]+\.jpg',buf)
if picType == '.jpg' :
    listurl = re.findall(r'img src=.([^\"^\']+\.jpg)?',buf)
if picType == '.jpeg' :
    listurl = re.findall(r'img src=.([^\"^\']+\.jpeg)?',buf)
if picType == '.png' :
    listurl = re.findall(r'img src=.([^\"^\']+\.png)?',buf)
if picType == '.gif' :
    listurl = re.findall(r'img src=.([^\"^\']+\.gif)?',buf)
for i in range(len(listurl)):     # 把字符img src="去掉
    listurl[i]=listurl[i].replace('img src="',"")
    if not re.match("http",listurl[i]):
        listurl[i]=url2 + listurl[i]
    print(listurl[i])
#"""
    

"""
#  已知图片url,只是序号不同
listurl = []
strs = "http://www.graphiscnn.com/evahbcms/upload/image/196/00"
for x in range(2,55):
    listurl.insert(x,strs+str(x)+".jpg")
"""
    

#3 抓取图片并保存到本地
i = 1
fpath = "D:\\pic3\\"
if not os.path.isdir(fpath):
    os.mkdir(fpath)
#for url in listurl: # 列表的第三张无法打开,导致失败
for url in islice(listurl, 4, None): 
    f=open(fpath + str(i)+picType,'wb')
    req = urllib.request.urlopen(url)
    buf = req.read()
    f.write(buf)
    print(i,picType)
    f.close()
    i+=1

"""
# UnicodeEncodeError: 'UCS-2' codec can't encode characters
# in position 73-73: Non-BMP character not supported in Tk
# 爬取的HTML页面中包含了Unicode下无法识别的字符,添加标识为①-③的三行代码
import requests
import sys  # ①
non_bmp_map = dict.fromkeys(range(0x10000,sys.maxunicode + 1),0xfffd) # ②

url = 'https://p.51vv.com/vp/kws2X4IT'
html = requests.get(url,headers=headers)
print(html.request.headers)
html = str(html.text).translate(non_bmp_map)  # ③
print(html)
"""

运行:

提取到的图片:

End