常用图像处理C函数

#include <graphics.h>
#include <windows.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>

#define GRP(x, y) GetRValue(getpixel(x, y))
#define GGP(x, y) GetGValue(getpixel(x, y))
#define GBP(x, y) GetBValue(getpixel(x, y))

#define PI 3.1415926535//圆周率
#define WIDTH 504//屏幕宽
#define HEIGHT 600//屏幕高
#define MODE 0//为零,灰度高斯模糊;为1, 彩色高斯模糊
#define S 2//锐化系数,百分制
#define R 2//搜索半径
#define GRAYSV 30//灰度阈值



int main(void)
{
void Sepia();//怀旧风格,老照片
void Comic();//连环画风格
void GBlur();//模糊,高斯模糊的特例
void Screen();//叠加模式:屏幕、滤色模式,需要复制图层
void SoftLight();//叠加模式:柔光,需要复制图层
void Multiply();//叠加模式:正片叠底模式,需要复制图层
void ColorDodge();//叠加模式:颜色减淡模式,需要复制图层
void MaxFilter();//滤镜,最大化,需要复制图层
void MinFilter();//滤镜,最小化,需要复制图层
void WoodCarving();//木雕效果,需要复制图层
void Pencil();//铅笔画效果,需要复制图层
void Sharpen();//锐化,需要复制图层
void Soften();//柔化,需要复制图层
void BgR();//交换蓝色和红色
void Diffuse();//扩散,需要复制图层
void CarveLR();//雕刻:自左向右,需要复制图层
void ColortoGRay();//彩色转灰度
void Invert();//反相
void CopyLayer();//图层复制
void LR();//左右颠倒,需要复制图层


initgraph(WIDTH, HEIGHT);//初始化600×600的绘图窗口
setbkcolor(WHITE);//设置背景色
cleardevice();//清空屏幕


loadimage(NULL, "F:beauty.jpg");
CopyLayer();
//ColortoGRay();
//Invert();
//ColorDodge(); 
//MinFilter();
//SoftLight();
//Screen();
//Multiply();
//WoodCarving();
//Pencil();
//Sharpen();
//BgR();
//Soften();
//Diffuse();
//CarveLR();
//LR();
//GBlur();
//Comic();
Sepia();

/*打印高斯变换矩阵
for(int i = 0; i <2 * N + 1; i++){
for(int j = 0; j <2 * N + 1; j++)
printf("%.8lf ", GaussT[i][j] );
putchar('\n');
}
*/
getch();
closegraph();

return 0;
}

//怀旧,老照片风格
void Sepia()
{
int br, bg, bb;
int mr, mg, mb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = (101 * br + 197 * bg + 48 * bb) >> 8;
mg = (89 * br + 176 * bg + 43 * bb) >> 8;
mb = (70 * br + 137 * bg + 34 * bb) >> 8;
putpixel(x, y, RGB(mr > 255? 255 : mr, mg > 255? 255 : mg, mb > 255? 255 : mb ));
}
}
//连环画风格,与灰度相似,但增大了对比度,整体明暗效果更强
void Comic()
{
void ColortoGRay();
int br, bg, bb;
int mr, mg, mb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = (abs(bg - bb + bg + br) * br) >> 8;
mg = (abs(bb - bg + bb + br) * br) >> 8;
mb = (abs(bb - bg + bb + br) * bg) >> 8;
putpixel(x, y, RGB(mr > 255? 255 : mr, mg > 255? 255 : mg, mb > 255? 255 : mb ));
}
ColortoGRay();
}

//模糊, 其实这是高斯模糊的一个特例而已。任意SIGMA的模糊,计算量太多,我就不写了
//因为SIGMA太小,所以不仔细看效果不明显,就不截图了
void GBlur()
{
int br, bg, bb;
int tem[3][3] = {1, 2, 1, 2, 4, 2, 1, 2, 1};//变换阵 * 16
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = bg = bb = 0;
for(int i = -1; i <= 1; i++)
for(int j = -1; j <= 1; j++){
br += GRP(x + i, y + i) * tem[i + 1][j + 1];
bg += GGP(x + i, y + i) * tem[i + 1][j + 1];
bb += GBP(x + i, y + i) * tem[i + 1][j + 1];
}
putpixel(x, y, RGB(br >>4, bg >> 4, bb >> 4)); //右移4位比除以16快多了
}
}

//左右替换, 图片不要太大,仿此可写其它函数
void LR()
{
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ )
putpixel(x, y, getpixel(WIDTH + WIDTH - x, y));
}

//柔光模式
void SoftLight()
{
int br, bg, bb;
int mr, mg, mb;
int cdr, cdg, cdb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = GRP(x + WIDTH, y);
mg = GGP(x + WIDTH, y);
mb = GBP(x + WIDTH, y);
cdr = (int)(mr > 127.5? br + (255 - br) * (mr - 127.5) / 127.5 * (0.5 - fabs(br - 127.5) / 255) :
br - br * (127.5 - mr) / 127.5 * (0.5 - fabs(br - 127.5) / 255));
cdg = (int)(mg > 127.5? bg + (255 - bg) * (mg - 127.5) / 127.5 * (0.5 - fabs(bg - 127.5) / 255) :
bg - bg * (127.5 - mg) / 127.5 * (0.5 - fabs(bg - 127.5) / 255));
cdb = (int)(mb > 127.5? bb + (255 - bb) * (mb - 127.5) / 127.5 * (0.5 - fabs(bb - 127.5) / 255) :
bb - bb * (127.5 - mb) / 127.5 * (0.5 - fabs(bb - 127.5) / 255));

putpixel(x, y, RGB(cdr, cdg, cdb));
}
}

//叠加模式
void OverLay()
{
int br, bg, bb;
int mr, mg, mb;
int cdr, cdg, cdb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = GRP(x + WIDTH, y);
mg = GGP(x + WIDTH, y);
mb = GBP(x + WIDTH, y);
cdr = (int)(br + (mr - 127.5) * (1 - fabs(br - 127.5) / 127.5));
cdg = (int)(bg + (mg - 127.5) * (1 - fabs(bg - 127.5) / 127.5));
cdb = (int)(bb + (mb - 127.5) * (1 - fabs(bb - 127.5) / 127.5));
putpixel(x, y, RGB(cdr, cdg, cdb));
}
}

//屏幕、滤色模式
void Screen()
{
int br, bg, bb;
int mr, mg, mb;
int cdr, cdg, cdb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = GRP(x + WIDTH, y);
mg = GGP(x + WIDTH, y);
mb = GBP(x + WIDTH, y);
cdr = br + mr - br * mr / 255;
cdg = bg + mg - bg * mg / 255;
cdb = bb + mb - bb * mb / 255;
putpixel(x, y, RGB(cdr, cdg, cdb));
}
}

//正片叠底模式
void Multiply()
{
int br, bg, bb;
int mr, mg, mb;
int cdr, cdg, cdb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);
mr = GRP(x + WIDTH, y);
mg = GGP(x + WIDTH, y);
mb = GBP(x + WIDTH, y);
cdr = br * mr / 255;
cdg = bg * mg / 255;
cdb = bb * mb / 255;
putpixel(x, y, RGB(cdr, cdg, cdb));
}
}

//颜色减淡 本点 = 基色 + 基色*混合色/(255 - 混合色)
void ColorDodge()
{
int br, bg, bb;
int mr, mg, mb;
int cdr, cdg, cdb;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
br = GRP(x, y);
bg = GGP(x, y);
bb = GBP(x, y);//基础色
mr = GRP(x + WIDTH, y);
mg = GGP(x + WIDTH, y);
mb = GBP(x + WIDTH, y);//混合色
cdr = (br + (br * mr) / (256 - mr)) > 255? 255 : (br + (br * mr) / (256 - mr));
cdg = (bg + (bg * mg) / (256 - mg)) > 255? 255 : (bg + (bg * mg) / (256 - mg));
cdb = (bb + (bb * mb) / (256 - mb)) > 255? 255 : (bg + (bg * mg) / (256 - mg));//结果色
putpixel(x, y, RGB(cdr, cdg, cdb));
}

//滤镜·最大化。
//滤镜·最大化。搜索周围的点,取最大值替代本像素
void MaxFilter()
{
int r, g, b;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
r = GRP(x, y);
g = GGP(x, y);
b = GBP(x, y);
for(int i = -1 * R; i <= R; i++)
for(int j = -1 * R; j <= R; j++){
r = (r < GRP(x + i + WIDTH, y + i)? GRP(x + i + WIDTH, y + i) : r);
g = (g < GGP(x + i + WIDTH, y + i)? GGP(x + i + WIDTH, y + i) : g);
b = (b < GBP(x + i + WIDTH, y + i)? GBP(x + i + WIDTH, y + i) : b);
}
putpixel(x, y, RGB(r, g, b));
}
}

//滤镜·最小化。
//滤镜·最小化。搜索周围的点,取最小值替代本像素
void MinFilter()
{
int r, g, b;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
r = GRP(x, y);
g = GGP(x, y);
b = GBP(x, y);
for(int i = -1 * R; i <= R; i++)
for(int j = -1 * R; j <= R; j++){
r = (r > GRP(x + i + WIDTH, y + i)? GRP(x + i + WIDTH, y + i) : r);
g = (g > GGP(x + i + WIDTH, y + i)? GGP(x + i + WIDTH, y + i) : g);
b = (b > GBP(x + i + WIDTH, y + i)? GBP(x + i + WIDTH, y + i) : b);
}
putpixel(x, y, RGB(r, g, b));
}
}

//木雕
//如果本点灰度与临近点灰度大于阈值,置白色;否则,置黑色
void WoodCarving()
{
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
if((abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y + 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y + 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y + 1)) > GRAYSV))
putpixel(x, y, WHITE);
else 
putpixel(x, y, BLACK);
}
}

//铅笔画
//如果本点灰度与临近点灰度大于阈值,置黑色;否则,置白色
void Pencil()
{
void ColortoGRay();
ColortoGRay();
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
if((abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y + 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y + 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x - 1 + WIDTH, y - 1)) > GRAYSV) ||
(abs(GRP(x + WIDTH, y) - GRP(x + 1 + WIDTH, y + 1)) > GRAYSV))
putpixel(x, y, BLACK);
else 
putpixel(x, y, WHITE);
}
}


//锐化,搜索周围半径为R范围内的点,
//差值 = 本点 - 周围点的平均值
//本点 = 本点 + 差值 * 锐化系数S
void Sharpen()
{
int r, g, b;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
r = g = b = 0;
for(int i = -1 * R; i <= R; i++)
for(int j = -1 * R; j <= R; j++){
if(i == 0 && j == 0) continue;
r += GRP(x + i + WIDTH, y + j);
g += GGP(x + i + WIDTH, y + j);
b += GBP(x + i + WIDTH, y + j);
}
r = GRP(x + WIDTH, y) * (1 + S) - r * S / (4 * R * R + 4 * R);
g = GGP(x + WIDTH, y) * (1 + S) - g * S / (4 * R * R + 4 * R);
b = GBP(x + WIDTH, y) * (1 + S) - b * S / (4 * R * R + 4 * R);
r = r > 255? 255 : r;
g = g > 255? 255 : g;
b = b > 255? 255 : b;
r = r < 0? 0 : r;
g = g < 0? 0 : g;
b = b < 0? 0 : b;
putpixel(x, y, RGB(r, g, b));
}
}

//柔化,搜索周围半径为R范围内的点,
//本点 = 本点及周围点的平均值
void Soften()
{
int r, g, b;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
r = g = b = 0;
for(int i = -1 * R; i <= R; i++)
for(int j = -1 * R; j <= R; j++){
r += GRP(x + i + WIDTH, y + j);
g += GGP(x + i + WIDTH, y + j);
b += GBP(x + i + WIDTH, y + j);
}
r /= (4 * R * R + 4 * R + 1);
g /= (4 * R * R + 4 * R + 1);
b /= (4 * R * R + 4 * R + 1);
putpixel(x, y, RGB(r, g, b));
}
}

//扩散,随机用周围R的一个点代替本点
void Diffuse()
{
int x0, y0;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
x0 = abs(rand()) % (2 * R + 1) - R;
y0 = abs(rand()) % (2 * R + 1) - R;
putpixel(x, y, getpixel(x + x0 + WIDTH, y + y0));
}

}

//雕刻,自左向右,本点 = 本点 - 右点 +127
void CarveLR()
{
int r, g, b;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
r = GRP(x, y) - GRP(x + 1, y) + 127;
g = GGP(x, y) - GGP(x + 1, y) + 127;
b = GBP(x, y) - GBP(x + 1, y) + 127;//127为调整后的亮度,可调
putpixel(x, y, RGB(r, g, b));
}
}

//图层复制
void CopyLayer()
{
Resize(NULL, WIDTH + WIDTH, HEIGHT);
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
putpixel(x + WIDTH, y, getpixel(x, y));
}
}

//彩色转变为灰度,将彩色点由计算出的灰度替代
//覆盖法
void ColortoGRay()
{
for(int x = 0; x < 2 * WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
int gRay = RGBtoGRAY(getpixel(x, y));
putpixel(x, y, RGB(gRay, gRay, gRay));
}
}

//反相,本点 = 255 -本点, 即互补
void Invert()
{
int IR, IG, IB;
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ ){
IR = 255 - GRP(x, y);
IG = 255 - GGP(x, y);
IB = 255 - GBP(x, y);
putpixel(x, y, RGB(IR, IG, IB));
}
}

//交换颜色中的红色和蓝色值
void BgR()
{
for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++ )
putpixel(x, y, BGR(getpixel(x, y)));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值