视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Photoshop图像亮度/对比度调整
2020-11-27 14:49:48 责编:小采
文档
简单介绍一下Photoshop图像亮度/对比度调整的原理:

一、对比度算法公式。

Photoshop对于对比度增量,是按给定值的正负分别处理的。

如果用newRGB表示图像像素新的R、G、B分量,RGB表示图像像素R、G、B分量,Threshold为给定的阀值,Contrast为对比度增量,当Contrast大于0时:

1) newRGB = RGB + (RGB - Threshold) * (1 / (1 - Contrast / 255) - 1)

其中,当Contrast等于255时(RGB - Threshold) * (1 / (1 - Contrast / 255) - 1)为无限(±),由于RGB最大最小值分别为255和0,因此,只能按Threshold来确定newRGB,即newRGB = RGB >= Threshold? 255 : 0,这实际就是设置图像阀值,图像由最多八种颜色组成,即红、黄、绿、青、蓝、紫及黑与白,在灰度图上也只有最多线。

当Contrast小于0时:

2) newRGB = RGB + (RGB - Threshold) * Contrast / 255

其中,当Contrast等于-255时,图像RGB各分量都等于阀值,图像呈全灰色,灰度图上只有1条线,即阀值灰度。

二、图像亮度调整。本文采用的是最常用的非线性亮度调整(Phoposhop CS3以下版本也是这种亮度调整方式,CS3及以上版本也保留了该亮度调整方式的选项)。

三、图像亮度/对比度综合调整算法。这个很简单,当亮度、对比度同时调整时,如果对比度大于0,现调整亮度,再调整对比度;当对比度小于0时,则相反,先调整对比度,再调整亮度。

下面是用BCB2007和GDI+位图数据写的Photoshop图像亮度/对比度调整全部代码,包括例子代码:

//---------------------------------------------------------------------------

// 定义ARGB像素结构
typedef union
{
ARGB Color;
struct
{
BYTE Blue;
BYTE Green;
BYTE Red;
BYTE Alpha;
};
}ARGBQuad, *PARGBQuad;
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

FORCEINLINE
INT CheckValue(INT value)
{
return value <= 0? 0 : value >= 255? 255 : value;
}
//---------------------------------------------------------------------------

VOID BrightAndContrast(BitmapData *data, INT bright, INT contrast, BYTE threshold)
{
FLOAT cv = contrast <= -255? -1.0f : contrast / 255.0f;
if (contrast > 0 && contrast < 255)
cv = 1.0f / (1.0f - cv) - 1.0f;

BYTE values[256];
for (INT i = 0; i < 256; i ++)
{
INT v = contrast > 0? CheckValue(i + bright) : i;
if (contrast >= 255)
v = v >= threshold? 255 : 0;
else
v = CheckValue(v + (INT)((v - threshold) * cv + 0.5f));
values[i] = contrast < 0? CheckValue(v + bright) : v;
}

PARGBQuad p = (PARGBQuad)data->Scan0;
INT offset = data->Stride - data->Width * sizeof(ARGBQuad);

for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset)
{
for (UINT x = 0; x < data->Width; x ++, p ++)
{
p->Blue = values[p->Blue];
p->Green = values[p->Green];
p->Red = values[p->Red];
}
}
}
//---------------------------------------------------------------------------

// 锁定GDI+位位图扫描线到data
FORCEINLINE
VOID LockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data)
{
Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight());
bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite,
PixelFormat32bppARGB, data);
}
//---------------------------------------------------------------------------

// GDI+位图扫描线解锁
FORCEINLINE
VOID UnlockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data)
{
bmp->UnlockBits(data);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
Gdiplus::Bitmap *bmp = new Gdiplus::Bitmap(L"d:\\source.jpg");
Gdiplus::Graphics *g = new Gdiplus::Graphics(Canvas->Handle);
g->DrawImage(bmp, 0, 0);

BitmapData data;
LockBitmap(bmp, &data);
BrightAndContrast(&data, 0, 100, 121);
UnlockBitmap(bmp, &data);
g->DrawImage(bmp, data.Width, 0);

delete g;
delete bmp;
}
//---------------------------------------------------------------------------

在亮度/对比度调整函数BrightAndContrast中,首先按前面介绍的原理制造了一个256个元素大小的查找表,然后对图像数据逐像素按R、G、B分量值在查找表中取得调整后的数据,因此处理速度相当快。

更多Photoshop图像亮度/对比度调整 相关文章请关注PHP中文网!

下载本文
显示全文
专题