为什么 AVIF 将成为下一代图片格式之王

news2024/11/15 22:24:32

AVIF的卓越优势

AVIF(AV1 Image File Format)正在迅速崛起,成为下一代网络图片格式的有力竞争者。作为基于AV1视频编码技术的图像格式,AVIF在多个方面展现出了令人瞩目的性能。

1. 卓越的压缩效率

与JPEG和WebP相比,AVIF能在保持相同图像质量的前提下,将文件大小减小30%至50%。这意味着:

  • 网站可呈现更高质量的图像
  • 显著减少带宽使用
  • 加快页面加载速度

2. 更广泛的色彩支持

  • 支持10位和12位的色彩
  • 兼容HDR(高动态范围)图像
  • 呈现更丰富、更逼真的视觉效果

这对摄影、电商等对图像质量要求较高的领域尤为重要。

3. 多功能性

  • 支持无损压缩
  • 支持透明度
  • 渐进式解码能力,允许图像在加载过程中逐步显示

4. 日益增长的浏览器支持

主流浏览器如Chrome、Firefox和Opera已开始支持AVIF,其他浏览器也在积极跟进。AVIF有望在不久的将来成为网络图片的主流格式。

如何在HTML中优化使用AVIF

为充分利用AVIF的优势,同时保证向下兼容性,建议使用以下HTML结构:

<picture>
    <!-- 性能表现更好的avif和webp图片格式 -->
    <source srcset="img/photo.avif" type="image/avif">
    <source srcset="img/photo.webp" type="image/webp">
    
    <!-- 最终的兜底方案 -->
    <img src="img/photo.jpg" alt="图片描述">
</picture>
  • 此结构确保在支持AVIF的浏览器中使用AVIF格式
  • 在支持WebP但不支持AVIF的浏览器中使用WebP格式
  • 在其他情况下回退到传统的JPEG格式
  • 注意:您的图片服务器必须提供avif和webp格式的图片

苹果CMS系统适配

<div class="movie-poster">
    <picture>
        <source srcset="{:rtrim(mac_url_img($obj.vod_pic), '.jpg,.png,.jpeg,.gif')}.avif" type="image/avif">
        <img src="{:mac_url_img($obj.vod_pic)}" alt="{$obj.vod_name}" referrerpolicy="no-referrer">
    </picture>
</div>

ImageMagick:AVIF转换利器

以下内容仅适用于Windows系统

安装ImageMagick

  1. 访问 ImageMagick官方下载页面
  2. 选择适合您系统的安装包
  3. 安装时注意:安装文件夹路径不能包含空格,建议新建专门文件夹

Image

设置系统环境变量

确保将ImageMagick的安装路径添加到系统的PATH环境变量中。

AVIF批量转换脚本

为方便批量处理图片,我制作了一个方便快捷的Shell脚本。该脚本可以:

  • 批量转换图片为AVIF格式

  • 记录处理过程

  • 输出错误信息和统计数据

  • 在Windows系统下使用Shell脚本,推荐安装Git,并使用Git Bash运行脚本

  • 下载Git:https://git-scm.com/downloads

  • List item

Image

使用方法
  1. 创建新文件,将以下脚本内容保存为avif_manager.sh
  2. 双击运行脚本文件
  3. 按照提示选择操作并输入图片目录路径
#!/bin/bash

# 初始化变量
img_dir=""

# 颜色定义
GREEN='\033[0;32m'
NC='\033[0m' # No Color

# 输出到控制台(绿色)
output() {
    echo -e "${GREEN}$1${NC}"
}

# 转换Windows路径为Bash兼容路径
convert_path() {
    local input_path="$1"
    if command -v cygpath &> /dev/null; then
        cygpath -u "$input_path"
    elif command -v wslpath &> /dev/null; then
        wslpath -u "$input_path"
    else
        echo "$input_path" | sed -e 's/^\([A-Za-z]\):/\/\L\1/' -e 's/\\/\//g'
    fi
}

# 设置目录
set_directories() {
    while [ -z "$img_dir" ]; do
        read -r -p "请输入图片目录路径: " input_dir
        img_dir=$(convert_path "$input_dir")
        if [ -d "$img_dir" ]; then
            output "图片目录已设置为: $img_dir"
        else
            echo "错误:目录不存在或无法访问,请重新输入。"
            img_dir=""
        fi
    done
}

# 打印统计信息
print_statistics() {
    local total_files=$1
    local total_original_size=$2
    local total_new_size=$3
    local error_count=$4

    local total_savings=$((total_original_size - total_new_size))
    local savings_percent=0

    if [ $total_original_size -ne 0 ]; then
        savings_percent=$(awk "BEGIN {printf \"%.2f\", ($total_savings / $total_original_size) * 100}")
    fi

    echo "----------------------------------------"
    echo "统计信息:"
    echo "处理的文件数:$total_files"
    echo "错误数:$error_count"
    echo "原始总大小:$(numfmt --to=iec-i --suffix=B $total_original_size)"
    echo "压缩后总大小:$(numfmt --to=iec-i --suffix=B $total_new_size)"
    echo "节省空间:$(numfmt --to=iec-i --suffix=B $total_savings) ($savings_percent%)"
    echo "----------------------------------------"
}

# 处理图片的通用函数
process_images() {
    local mode=$1
    output "开始处理图片 - $mode"
    output "当前图片目录: $img_dir"
    
    if [ ! -d "$img_dir" ]; then
        echo "错误:图片目录不存在"
        return
    fi
    
    local total_files=0
    local total_original_size=0
    local total_new_size=0
    local error_count=0

    while IFS= read -r -d '' file; do
        ((total_files++))
        filename=$(basename "$file")
        dir=$(dirname "$file")
        avif_filename="${filename%.*}.avif"
        
        local original_size=$(stat -c%s "$file")
        ((total_original_size += original_size))

        if magick "$file" -quality 70 -define avif:compression-level=3 -define avif:effort=4 "${dir}/${avif_filename}"; then
            local new_size=$(stat -c%s "${dir}/${avif_filename}")
            ((total_new_size += new_size))
            
            if [ "$mode" = "转换并删除原图" ]; then
                if rm "$file"; then
                    output "$filename: 已转换并删除原图"
                else
                    echo "$filename: 转换成功,但无法删除原图"
                    ((error_count++))
                fi
            else
                output "$filename: 已转换"
            fi
        else
            echo "$filename: 转换失败"
            ((error_count++))
        fi
    done < <(find "$img_dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -print0)

    output "处理完成 - $mode"
    print_statistics $total_files $total_original_size $total_new_size $error_count
}

# 转换并删除原图
convert_and_delete_original() {
    process_images "转换并删除原图"
}

# 转换并保留原图
convert_and_keep_original() {
    process_images "转换并保留原图"
}

# 恢复原图(删除AVIF)
restore_original() {
    output "开始恢复原图 - 删除AVIF"
    output "当前图片目录: $img_dir"
    
    if [ ! -d "$img_dir" ]; then
        echo "错误:图片目录不存在"
        return
    fi
    
    local total_files=0
    local total_size=0
    local error_count=0

    while IFS= read -r -d '' file; do
        ((total_files++))
        filename=$(basename "$file")
        
        local file_size=$(stat -c%s "$file")
        ((total_size += file_size))

        if rm "$file"; then
            output "$filename: 已删除"
        else
            echo "$filename: 删除失败"
            ((error_count++))
        fi
    done < <(find "$img_dir" -type f -iname "*.avif" -print0)

    output "恢复完成 - 删除AVIF"
    print_statistics $total_files $total_size 0 $error_count
}

# 主菜单
show_menu() {
    clear
    echo "========================================="
    echo "            AVIF 图片管理器              "
    echo "========================================="
    echo "1. 设置目录"
    echo "2. 转换为AVIF并删除原图"
    echo "3. 转换为AVIF并保留原图"
    echo "4. 恢复原图(删除AVIF)"
    echo "5. 退出"
    echo "========================================="
    echo
    read -p "请选择操作 (1-5): " choice
    
    case $choice in
        1) set_directories ;;
        2) 
            if [ -z "$img_dir" ]; then
                set_directories
            fi
            convert_and_delete_original 
            ;;
        3) 
            if [ -z "$img_dir" ]; then
                set_directories
            fi
            convert_and_keep_original 
            ;;
        4) 
            if [ -z "$img_dir" ]; then
                set_directories
            fi
            restore_original 
            ;;
        5) exit 0 ;;
        *) echo "无效选择,请重试。" ;;
    esac
    
    echo
    read -p "操作完成,按回车键返回主菜单..."
}

# 主程序
while true; do
    show_menu
done

通过这个脚本,您可以轻松地管理AVIF图片转换过程,包括设置目录、转换图片(可选是否保留原图)以及恢复原图等功能。脚本还会提供详细的统计信息,帮助您了解转换效果。


通过采用AVIF格式并使用这些工具和方法,您可以显著提升网站的图片加载性能,为用户提供更佳的浏览体验。随着AVIF支持的不断扩大,现在正是开始在您的项目中应用这一先进图片格式的最佳时机。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2154557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

torch模型量化方法总结

0.概述 模型训练完成后的参数为float或double类型&#xff0c;而装机&#xff08;比如车载&#xff09;后推理预测时&#xff0c;通常都会预先定点&#xff08;量化&#xff09;为int类型参数&#xff0c;相应的推理的精度会有少量下降&#xff0c;但不构成明显性能下降&#…

CO-锁存器(Latch)

1.描述 锁存器(Latch)&#xff0c;是数字电路中的一种具有记忆功能的逻辑元件&#xff0c;是一种对脉冲电平敏感的存储单元电路&#xff0c;可以在特定输入脉冲电平作用下改变状态&#xff0c;利用电平控制数据的输入&#xff0c;包括不带使能控制的锁存器和带使能控制的锁存器…

sql执行流程经典案例分析

现在有联合索引(a,b),select* form tb where b xx group by a执行流程是什么样子的? CREATE TABLE IF NOT EXISTS test(id INT(10) NOT NULL AUTO_INCREMENT COMMENT主键,a INT(10) NULL,b INT(10) NULL,PRIMARY KEY(id),INDEX idx_a_b(a,b))ENGINE INNODB;INSERT INTO test…

【Unity-UGUI组件拓展】| Image 组件拓展,支持FIlled和Slice功能并存

🎬【Unity-UGUI组件拓展】| Image 组件拓展,支持FIlled和Slice功能并存一、组件介绍二、组件拓展方法三、完整代码💯总结🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏…

Linux:login shell和non-login shell以及其配置文件

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 shell是Linux与外界交互的程序&#xff0c;登录shell有两种方式&#xff0c;login shell与non-login shell&#xff0c;它们的区别是读取的配置文件不同&#xff0c;本…

TypeScript入门 (三)数据类型

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。本文旨在全面介绍 TypeScript 中的各种数据类型&#xff0c;帮助读者深入理解每种数据类型的用法、内置属性…

LabVIEW提高开发效率技巧----自动化测试和持续集成

在大型项目中&#xff0c;自动化测试和持续集成是提高开发效率和代码质量的关键手段。通过这些技术&#xff0c;开发者能够在开发的早期阶段快速发现问题&#xff0c;减少后期调试的工作量&#xff0c;并且能够确保代码的稳定性和可维护性。以下是这两个概念如何在LabVIEW开发中…

Docker Networking Tutorial (Bridge - None - Host - IPvlan - Macvlan )

In this article, We will talk about the network of docker. Therere have five types of docker network. 一、Bridge The default network of docker network type. You can use : docker network ls docker network create --driver bridge my_bridge_network ##The CID…

什么是 GPT?通过图形化的方式来理解 Transformer 架构

Predict, sample, repeat 预测、取样、重复 GPT 是 Generative Pre-trained Transformer 的缩写。首个单词较为直接&#xff0c;它们是用来生成新文本的机器人。“Pre-trained” 指的是模型经历了从大量数据中学习的过程&#xff0c;这个词暗示了该模型还有进一步在特定任务中…

移动技术开发:ListView水果列表

1 实验名称 ListView水果列表 2 实验目的 掌握自定义ListView控件的实现方法 3 实验源代码 布局文件代码&#xff1a; activity_main.xml: <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.androi…

Java 中Lock接口锁的使用

一. Lock接口下的实现类 在Java中&#xff0c;Lock 接口是 java.util.concurrent.locks 包中的一部分&#xff0c;它提供了比 synchronized 更丰富的锁操作。Lock 接口的实现类包括 ReentrantLock&#xff08;可重入锁&#xff09;、ReadWriteLock&#xff08;读写锁&#xff…

从零开始学习TinyWebServer

写在前面 项目参考&#xff1a;https://github.com/qinguoyi/TinyWebServer 写作框架/图参考&#xff1a;https://blog.csdn.net/qq_52313711/article/details/136356042?spm1001.2014.3001.5502 原本计划是&#xff0c;先将项目代码大概看一遍&#xff0c;然后再着手实现一下…

【hot100-java】【组合总和】

R8-回溯篇 印象题&#xff0c;很基本的回溯 class Solution {void backtrack(List<Integer> state,int target,int[] choices,int start,List<List<Integer>> ret){//子集和等于target&#xff0c;记录解if (target0){ret.add(new ArrayList<>(state)…

LeetCode讲解篇之1343. 大小为 K 且平均值大于等于阈值的子数组数目

文章目录 题目描述题解思路题解代码 题目描述 题解思路 题目让我们求长度为k的子数组并且该子数组的平均值大于threshold&#xff0c;对于这题&#xff0c;我们可以考虑维护一个长度为k的窗口&#xff0c;窗口不断向右滑动&#xff0c;遍历所有长度为k的子数组&#xff0c;我们…

低版本SqlSugar的where条件中使用可空类型报语法错误

SQLServer数据表中有两列可空列&#xff0c;均为数值类型&#xff0c;同时在数据库中录入测试数据&#xff0c;Age和Height列均部分有值。   使用SqlSugar的DbFirst功能生成数据库表类&#xff0c;其中Age、Height属性均为可空类型。   开始使用的SqlSugar版本较低&…

win11 wsl2安装ubuntu22最快捷方法

操作系统是win11&#xff0c;wsl版本是wsl2&#xff0c;wsl应该不用多介绍了&#xff0c;就是windows上的虚拟机&#xff0c;在wsl上可以很方便的运行Linux系统&#xff0c;性能棒棒的&#xff0c;而且wsl运行的系统和win11主机之间的文件移动是无缝的&#xff0c;就是两个系统…

力扣115-不同的子序列(Java详细题解)

题目链接&#xff1a;不同的子序列 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 5.如果没有ac打印dp数组 利于debug。 每一个dp题目…

Spring IDEA 2024 安装Lombok插件

1.简介 Lombook插件的Data标签可以自动生成类的get和set以及toString方法。 2.安装步骤 在idead设置的插件中搜索lombok插件&#xff0c;安装。 在Spring项目的pom.xml中添加依赖项 <dependency><groupId>org.projectlombok</groupId><artifactId…

数据结构与算法——Java实现 7.习题——反转链表

当你穿过了暴风雨&#xff0c;你已不是原来那个人 —— 24.9.21 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输…

echarts标注legend的配置

代码&#xff1a; legend: [{top: bottom, //上下位置 top center bottom 还可以用百分比50%等orient: horizontal, // 竖立 vertical horizontal 水平的// right: 0, //靠右 还可以用百分比 50%等// left: 0,// 靠左 还可以用百分比 50%等// 左右位置 否则居中itemWidth: …