#include #include <atlimage.h> #include using namespace std;

class HSV { public: double H; // 色度 [0, 360) double S; // 饱和度 [0, 1] double V; // 亮度 [0, 1] HSV() {} HSV(double h, double s, double v) : H(h), S(s), V(v) {} };

double getMax(double a, double b, double c) { // 需要实现,返回三个参数的最大值 return max(max(a, b), c); }

double getMin(double a, double b, double c) { // 需要实现,返回三个参数的最小值 return min(min(a, b), c); }

double getMod(double a, int b) { return a - (int)(a / b) * b; }

HSV RGB2HSV(COLORREF c) { // 需要实现,把 COLORREF(RGB)类对象 c 转换为 HSV 类对象,返回 double R = GetRValue(c); double G = GetGValue(c); double B = GetBValue(c); R = R / 255; G = G / 255; B = B / 255; double V = getMax(R, G, B); double S; if (V != 0) S = (V - getMin(R, G, B)) / V; else S = 0; double H; if (V == getMin(R, G, B)) H = 0; else if (V == R) H = 60 * (G - B) / (V - getMin(R, G, B)); else if (V == G) H = 120 + (60 * (B - R) / (V - getMin(R, G, B))); else if (V == B) H = 240 + (60 * (R - G) / (V - getMin(R, G, B))); if (H < 0) H = H + 360; return HSV(H, S, V); }

COLORREF HSV2RGB(HSV hsv) { // 需要实现,把 HSV 类对象 hsv 转换为 COLORREF(RGB)类对象,返回 double C, X, m; double R, G, B; double H = hsv.H, S = hsv.S, V = hsv.V; C = V * S; double mod = getMod(H / 60, 2); X = C * (1 - abs(mod - 1)); m = V - C; if (0 <= H && H < 60) { R = C; G = X; B = 0; } else if (60 <= H && H < 120) { R = X; G = C; B = 0; } else if (120 <= H && H < 180) { R = 0; G = C; B = X; } else if (180 <= H && H < 240) { R = 0; G = X; B = C; } else if (240 <= H && H < 300) { R = X; G = 0; B = C; } else if (300 <= H && H < 360) { R = C; G = 0; B = X; } R = round((R + m) * 255); G = round((G + m) * 255); B = round((B + m) * 255); return RGB(R, G, B); }

int main() { LPCTSTR srcFilePath = _T("6.jpg"); LPCTSTR destFilePath = _T("6-ans.jpg"); CImage srcImage; srcImage.Load(srcFilePath); int width = srcImage.GetWidth(); int height = srcImage.GetHeight(); int bpp = srcImage.GetBPP(); int pitch = srcImage.GetPitch(); BYTE* pData = (BYTE*)srcImage.GetBits(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { BYTE b = *(pData + pitch * y + x * bpp / 8 + 0); BYTE g = *(pData + pitch * y + x * bpp / 8 + 1); BYTE r = *(pData + pitch * y + x * bpp / 8 + 2); COLORREF c = RGB(r, g, b); HSV h = RGB2HSV(c); if (h.V < 0.4) h.V *= 3; else if (h.V > 0.995) h.V /= 1.065; // 0.939 else if (h.V > 0.99) h.V /= 1.06; // 0.938 else if (h.V > 0.985) h.V /= 1.055; // 0.938 else if (h.V > 0.98) h.V /= 1.05; // 0.937 else if (h.V > 0.975) h.V /= 1.045; // 0.937 else if (h.V > 0.97) h.V /= 1.04; // 0.937 else if (h.V > 0.965) h.V /= 1.035; else if (h.V > 0.96) h.V /= 1.03; else if (h.V > 0.955) h.V /= 1.025; else if (h.V > 0.95) h.V /= 1.02; else if (h.V > 0.945) h.V /= 1.015; COLORREF ans = HSV2RGB(h); *(pData + pitch * y + x * bpp / 8 + 0) = GetBValue(ans); *(pData + pitch * y + x * bpp / 8 + 1) = GetGValue(ans); *(pData + pitch * y + x * bpp / 8 + 2) = GetRValue(ans); } } srcImage.Save(destFilePath); return 0; }

// 解释一下这段代码内容:这段代码是一个 C++ 程序,用于将一张图片转换为 HSV 颜色空间,并对图片的亮度进行调整后再转换回 RGB 颜色空间。具体的步骤如下:

// 1. 首先定义了一个 HSV 类,包含了色度(H)、饱和度(S)和亮度(V)三个成员变量。 // 2. 然后定义了一些辅助函数,包括获取三个数中的最大值(getMax)、最小值(getMin)和取模(getMod)。 // 3. 实现了 RGB 转 HSV 的函数 RGB2HSV,该函数接收一个 COLORREF 类型的参数 c,将其转换为 HSV 类型对象后返回。具体的转换过程如下: // - 首先将 RGB 的三个分量值除以 255,将其转换为 [0, 1] 的范围内的值。 // - 计算亮度 V,取 R、G、B 三个分量的最大值。 // - 计算饱和度 S,如果 V 不为 0,则为 (V - 最小值) / V,否则为 0。 // - 计算色度 H,根据 V 和最小值的关系,分别计算出 R、G、B 对应的情况。 // 4. 实现了 HSV 转 RGB 的函数 HSV2RGB,该函数接收一个 HSV 类型的参数 hsv,将其转换为 COLORREF 类型对象后返回。具体的转换过程如下: // - 计算出 C、X 和 m 三个变量,分别代表 HSV 颜色空间中的色度、饱和度和亮度。 // - 根据色度 H 的取值范围,分别计算出 RGB 三个分量的值。 // 5. 主函数中加载了一张图片,并获取了图片的宽度、高度、色彩模式等信息。 // 6. 使用嵌套循环遍历图片的每个像素点,获取该像素点的 RGB 值,并将其转换为 HSV 值。 // 7. 对 HSV 值中的亮度进行调整,根据亮度的不同范围,进行相应的操作。 // 8. 将调整后的 HSV 值转换回 RGB 值,并更新原图像中对应像素点的 RGB 值。 // 9. 最后保存修改后的图像。

C++ 图片亮度调整代码:利用 HSV 颜色空间进行亮度调节

原文地址: https://www.cveoy.top/t/topic/o4EP 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录