在项目中遇到了上传头像图片的需求,包括两个部分,一个是头像的上传。另一个是上传后头像图片的显示。

头像的上传

头像的上传和普通的图片上传几乎没有不同,但通常需要对上传的图片进行限制,例如限制图片格式为png/jpg,图片大小的限制,图片像素的限制等。

图片格式的限制

限制为图片格式[‘jpg’, ‘jpeg’, ‘png’, ‘bmp’],如果头像允许显示动态图,也可以允许gif,不过考虑到大小,一般不允许。最好给予用户提示文案,限定一种最友好的图片格式,例如png。

图片大小的限制

头像一般不允许过大的图片,因为引用的页面可能比较多,所以一般限制在百k的级别。例如120k。

图片像素的限制

头像一般为正方形,所以最好有文案提示用户上传正方形的图片,而且给予限定范围,例如“尺寸需小于256px*256px且大于120px*120px”,同时给出最佳的头像显示像素,采用此种像素,在应用中大部分情况下既不压缩也不拉伸。由于大部分情况下用户不会上传完全正方形的图片,所以在一定的宽高比例内,也应该允许上传。

提示语

包括:

1. 默认提示语
2. 默认上传失败提示语
3. 上传成功提示语
4. 图片格式不正确
5. 图片大小超过限制
6. 图片宽高比例不正确

上传进度

有时也需要显示上传进度,不过一般而言图片文件不会很大,如果单单只是图片的上传,也可以使用loading图。

样例

最简单的上传头像图片的逻辑代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<input
class="upload-example"
type="file"
placeholder="选择图片"
onchange="onChange"/>
<script type="text/javascript">
function onChange(e) {
let file = e.target.files[0];
check(file); // 检查待上传文件是否符合要求
let formData = new FormData();
formData.append('file', file, file.name);
upload(formData);
}
function upload(formData) {
axios.request({
method: 'post',
url: uploadUrl,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(
...
)
}
function check(file) {
// file.type in [typeLimit]
// file.size < sizeLimit
...
}
</script>

头像的显示

头像的显示也有两种方案,一种是显示为img,另一种是显示为div,然后通过将背景设置为头像图片来显示。两种都需要设置 border-radiu: 50%; 。下面演示下两种显示方案。我们假设头像的区域范围为120px*120px。用户上传了几种头像,一种是实际图片大小为400px*400px,另一种为800px*400px,还有一种为120px*60px。

用img标签显示

设置图片的宽和高,通常长度相同,然后设置 border-radiu: 50%; 即可,这样如果用户上传的图片不是正方形的话,在相应的方向上会有拉伸或压缩的效果,如下图二,因为宽度大于高度,且大于120px所以产生了在宽度上压缩的效果。下图三因为高度小于宽度,且小于120px,所以在高度上产生了拉伸的效果。可以使用 object-fit: cover 属性来使图片更合适。

效果图:

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style type="text/css">
img.avator-example-1 {
height: 120px;
width: 120px;
border-radius: 50%;
}
img.avator-example-1.object-fit {
object-fit: cover;
}
</style>

<img class="avator-example-1" src="/blog/static/imgs/avator/400_400.jpg"></img><!-- 图一 -->
<img class="avator-example-1" src="/blog/static/imgs/avator/800_400.jpg"></img><!-- 图二 -->
<img class="avator-example-1" src="/blog/static/imgs/avator/120_60.jpg"></img><!-- 图三 -->
<img class="avator-example-1 object-fit" src="/blog/static/imgs/avator/120_60.jpg"></img><!-- 图四 -->

用div标签的background-image来显示

设置区域的 background-image 为用户上传的图片然后设置 background-size 属性即可,例如设置 background-size: 120px 120px; 则会在相应的方向上压缩或拉伸,如下图三。如果设置 background-size: auto 120px; 则图片的高度会占满空间,宽度会取120px,如下图二。这和设置成 background-size: cover; 的效果是相同的,如下图四,五。注意,因为此处举例的图片为宽度大于高度,所以设置 background-size: auto 120px; 会呈现圆形,如果高度大于宽度,则应当设置 backgounrd-size: 120px auto;

效果图:

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<style type="text/css">
div.avator-example-2,
div.avator-example-3,
div.avator-example-4,
div.avator-example-5 {
height: 120px;
width: 120px;
border-radius: 50%;
background-color: #fff;
background-size: 120px 120px;
background-repeat: no-repeat;
background-image: url(/blog/static/imgs/avator/800_400.jpg);
}
div.avator-example-2 {
background-image: url(/blog/static/imgs/avator/400_400.jpg);
}
div.avator-example-3 {
background-size: auto 120px;
}
div.avator-example-5,
div.avator-example-6 {
background-size: cover;
}
div.avator-example-6 {
background-image: url(/blog/static/imgs/avator/120_60.jpg);
}
</style>

<div class="avator-example-2"></div><!-- 图一 -->
<div class="avator-example-3"></div><!-- 图二 -->
<div class="avator-example-4"></div><!-- 图三 -->
<div class="avator-example-5"></div><!-- 图四 -->
<div class="avator-example-6"></div><!-- 图五 -->

object-fit

object-fit 属性用来控制 img、video 元素在容器中的显示方式,尤其是元素的宽高和容器不一致时。

  • cover 将会正比例的调整图片的大小以适应容器的宽高比,使得图片被裁剪。
  • contain会成比例的调整图片的大小以使得图片可以完整的展示,但是容器中不展示图片的部分将会展示为 background-color 的颜色。
  • 默认值为 fill,图片的宽高和容器不一致时图片会被压缩或拉伸。
  • none 将不会处理图片,图片会被平铺在容器中,既不压缩也不拉伸。

backgound-size

backgound-size 属性用来指定背景图片(background-image)的大小,以像素、百分比来显示,或者通过 covercontain 属性对图片进行拉伸或压缩。

  • 值为像素值时,可以设定背景图片的高度和宽度。第一个值设置宽度,第二个值设置高度。如果只给出一个值,第二个会被设置为 auto
  • 值为百分比时,将计算相对于背景定位区域的百分比。100% 100% 表示将背景图片的宽高设置为与容器一致,如果背景图片的宽高比与容器不一致,则会在特定方向上出现压缩或拉伸的效果。
  • 值为 cover 时,会保持图片的宽高比并将图片缩放成完全覆盖背景定位区域的大小。
  • 值为 contain 时,会保持图片的宽高比并将图片缩放到背景区域能够完全包含图片的大小。
  • 默认值为 auto ,既不压缩也不拉伸。