视频亮度对比度
调整亮度 / 对比度 / 饱和度 / 色温
亮度/对比度/饱和度/gamma
调整亮度 / 对比度 / 饱和度 / 色温
视频处理涉及复杂的解码 / 编码 / 滤镜操作,桌面 FFmpeg(开源 / 免费)是业界事实标准。安装 5 分钟,运行如下命令一次解决:
用 Homebrew,5 秒安装
Debian/Ubuntu/Fedora
无需本地安装
按上方系统对应的命令安装。验证:ffmpeg -version 应输出版本号。
将 input.mp4 改为你的实际视频文件路径。
用终端 (Terminal / cmd / PowerShell) 切到视频所在目录,粘贴命令并回车。
短视频几秒,长视频几分钟。输出文件出现在同目录。
参数范围:brightness -1 到 1;contrast 0 到 4(1=原始);saturation 0 到 3。
了解工具定位 · 使用场景 · 对比优势
老旧监控视频或家庭录像因曝光不足导致画面过暗,人脸细节完全淹没在阴影中。使用本工具同时提升亮度(+30%)和对比度(+20%),并微调 gamma 至 1.2,可在不产生明显噪点的情况下恢复暗部纹理,让被摄主体轮廓清晰可辨。
电商摄影师拍摄的静物照片因环境光色温偏差导致饱和度不足,商品颜色偏灰。通过本工具将饱和度从 0.7 提升至 1.2,配合对比度 +15%,使产品色彩更鲜艳、边缘更锐利,无需进入 Photoshop 即可快速产出符合平台要求的白底图。
主播在室内补光灯下录制时,面部高光区域过曝、背景暗部细节丢失。使用本工具降低亮度(-10%)并提高对比度(+25%),同时将 gamma 设为 0.9 以压缩高光、提亮阴影,使主播面部肤色均匀,背景道具纹理可辨。
阴天或逆光环境下拍摄的短视频,整体画面发灰、缺乏层次感。本工具通过同时增加对比度(+30%)和饱和度(+15%),并调整 gamma 至 1.1,可有效去除雾感,使天空蓝色更纯净、人物肤色更自然,无需专业调色软件。
| 维度 | 本工具 | 竞品 A(Adobe Premiere Pro) | 传统方法(视频编辑软件) |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,视频不上传服务器 | 需上传至 Adobe 云或本地处理,涉及 Adobe 账户 | 完全本地处理,无网络传输 |
| 处理速度 | 1-3 秒(取决于视频大小和浏览器性能) | 数秒至数分钟(取决于渲染设置和项目复杂度) | 数分钟至数小时(取决于软件渲染效率和手动操作) |
| 离线可用 | 完全离线(WASM 在浏览器本地运行) | 需联网启动和验证许可证 | 完全离线(软件安装后) |
| 大小限制 | 受浏览器内存限制(通常 2GB 以内视频) | 无严格限制(取决于存储和硬件) | 无严格限制(取决于存储和硬件) |
| 收费 | 免费 | 按月/年订阅(约 ¥150+/月) | 一次性购买或订阅(如 Final Cut Pro ¥1998) |
| 注册 | 无需注册 | 需要 Adobe ID 登录 | 通常需要购买许可证,无需在线注册 |
| 操作门槛 | 拖拽即用,无学习成本 | 需要学习专业剪辑软件操作 | 需要学习专业剪辑软件操作 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 亮度=10, 对比度=1.2, 饱和度=1.5, gamma=0.8 | 画面整体提亮,色彩更鲜艳,暗部细节增强 | 典型常规场景:视频偏暗偏灰,需要提亮和增色 |
| 亮度=0, 对比度=1.0, 饱和度=1.0, gamma=1.0 | 画面无任何变化,与原视频一致 | 边界 case:所有参数设为默认值,验证无副作用 |
| 亮度=255, 对比度=2.0, 饱和度=2.0, gamma=0.5 | 画面严重过曝,色彩失真,暗部完全消失 | 边界 case:参数最大值组合,测试极端效果 |
| 亮度=-255, 对比度=0.0, 饱和度=0.0, gamma=3.0 | 画面全黑,无任何可见内容 | 边界 case:参数最小值组合,输出全黑帧 |
| 亮度=30, 对比度=1.0, 饱和度=0.0, gamma=1.0 | 画面变为灰度,但整体偏亮 | 易错 case:饱和度设为0得到黑白效果,但亮度仍生效 |
| 亮度=0, 对比度=1.0, 饱和度=1.0, gamma=2.2 | 画面暗部更暗,亮部更亮,对比感增强 | 典型场景:gamma校正用于调整显示器色温匹配 |
| 亮度=50, 对比度=0.5, 饱和度=1.2, gamma=1.0 | 画面柔和,细节保留,色彩轻微增强 | 典型场景:老旧视频修复,避免过度处理 |
gamma=-0.5gamma=1.2Gamma 校正公式为输出 = 输入^(1/gamma),负值在数学上无意义,FFmpeg 会报错或输出全黑画面。有效范围通常 0.1-10.0,1.0 为原始值。
brightness=50%brightness=0.3FFmpeg 的 eq 滤镜中 brightness 取值范围是 -1.0 到 1.0,0 为原始。写成百分比会被解析为字符串而非数值,导致滤镜静默失败。
eq=brightness=0.2:contrast=1.5:gamma=1.0eq=contrast=1.5:brightness=0.2:gamma=1.0FFmpeg eq 滤镜内部按 contrast→brightness→gamma 顺序处理。先调亮度再调对比度会使亮度偏移被对比度放大,产生过曝。
saturation=0saturation=1.0(原始)或 0.5(半灰度)饱和度 0 输出完全灰度视频,但 FFmpeg 不保留原始色度信息。后续再调高饱和度也不会恢复颜色,需重新处理原视频。
gamma=2.5:brightness=0.8gamma=1.8:brightness=0.2Gamma 改变中灰亮度,brightness 线性偏移整体。两者同时大幅调整会导致暗部或亮部严重裁切(clipping),细节丢失不可逆。
对 BT.709 视频直接套用 BT.2020 的 Gamma 值先通过 setparams=color_primaries=bt709:color_trc=bt709 明确色彩空间不同色彩空间(BT.601/BT.709/BT.2020)的 Gamma 曲线不同。直接套用 Gamma 值会导致色彩偏移,尤其红色和肤色。
brightness=1brightness=1.0FFmpeg 的 eq 滤镜参数为浮点型。整数 1 会被隐式转为 1.0,但后续对比度等参数若用整数(如 contrast=2)可能因类型推断导致精度丢失。
公式推导 · 流程图解 · 依据出处
O = (I - 128) × C + 128 + B
O — 输出像素值(0-255)I — 输入像素值(0-255)C — 对比度增益系数(≥0)B — 亮度偏移量(-255 到 255)原图某像素值 I=100,设置对比度 C=1.5、亮度 B=20。则 O = (100-128)×1.5 + 128 + 20 = (-28)×1.5 + 148 = -42 + 148 = 106。输出像素值 106,比原图更亮且对比增强。
适用于 8 位 RGB 或灰度图像(0-255 整数像素值)。超出 0-255 范围时会被截断。Gamma 校正和饱和度调整需额外公式,不在此式覆盖范围。
3 种主流语言 · 复制即用
import cv2
import numpy as np
# 读取图像
img = cv2.imread('input.jpg')
# 亮度(+50)、对比度(1.5)、饱和度(1.3)、Gamma(0.8)
alpha = 1.5 # 对比度
beta = 50 # 亮度
# 亮度和对比度
adjusted = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
# 饱和度(HSV空间)
hsv = cv2.cvtColor(adjusted, cv2.COLOR_BGR2HSV).astype(np.float32)
hsv[:,:,1] = np.clip(hsv[:,:,1] * 1.3, 0, 255)
adjusted = cv2.cvtColor(hsv.astype(np.uint8), cv2.COLOR_HSV2BGR)
# Gamma校正
gamma = 0.8
lookup = np.array([(i / 255.0) ** (1.0 / gamma) * 255 for i in range(256)]).astype(np.uint8)
adjusted = cv2.LUT(adjusted, lookup)
cv2.imwrite('output.jpg', adjusted)package main
import (
"image"
"image/color"
"image/jpeg"
"math"
"os"
)
func main() {
file, _ := os.Open("input.jpg")
defer file.Close()
src, _, _ := image.Decode(file)
bounds := src.Bounds()
dst := image.NewRGBA(bounds)
alpha := 1.5 // 对比度
beta := 50.0 // 亮度
gamma := 0.8 // Gamma
sat := 1.3 // 饱和度
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := src.At(x, y).RGBA()
// 转为0-255
rf := float64(r>>8) * alpha + beta
gf := float64(g>>8) * alpha + beta
bf := float64(b>>8) * alpha + beta
// Gamma
rf = math.Pow(rf/255.0, 1.0/gamma) * 255
gf = math.Pow(gf/255.0, 1.0/gamma) * 255
bf = math.Pow(bf/255.0, 1.0/gamma) * 255
// 饱和度(简化:RGB转HSV再转回)
// 此处省略完整HSV转换,实际可用colorful库
dst.Set(x, y, color.RGBA{
R: uint8(math.Min(math.Max(rf, 0), 255)),
G: uint8(math.Min(math.Max(gf, 0), 255)),
B: uint8(math.Min(math.Max(bf, 0), 255)),
A: uint8(a >> 8),
})
}
}
out, _ := os.Create("output.jpg")
defer out.Close()
jpeg.Encode(out, dst, nil)
}// 浏览器端 Canvas 实现(无需外部库)
function adjustVideoFrame(canvas, brightness, contrast, saturation, gamma) {
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// 亮度和对比度
r = r * contrast + brightness;
g = g * contrast + brightness;
b = b * contrast + brightness;
// Gamma
r = Math.pow(r / 255, 1 / gamma) * 255;
g = Math.pow(g / 255, 1 / gamma) * 255;
b = Math.pow(b / 255, 1 / gamma) * 255;
// 饱和度(简化:加权平均转灰度再插值)
const gray = 0.299 * r + 0.587 * g + 0.114 * b;
r = gray + (r - gray) * saturation;
g = gray + (g - gray) * saturation;
b = gray + (b - gray) * saturation;
data[i] = Math.min(255, Math.max(0, r));
data[i + 1] = Math.min(255, Math.max(0, g));
data[i + 2] = Math.min(255, Math.max(0, b));
}
ctx.putImageData(imageData, 0, 0);
}
// 使用示例:adjustVideoFrame(canvas, 50, 1.5, 1.3, 0.8);8 个高频疑问