C语言如何在图片上画一个圆
创作时间:
作者:
@小白创作中心
C语言如何在图片上画一个圆
引用
1
来源
1.
https://docs.pingcode.com/baike/1185715
本文将详细介绍如何通过使用图形库和实现Bresenham算法在图片上绘制一个圆。
一、使用图形库
1.1 使用SDL库
SDL(Simple DirectMedia Layer)是一种跨平台的多媒体库,适用于游戏和多媒体应用。使用SDL库可以方便地在图片上绘制图形,包括圆。
安装和初始化SDL库
首先,需要安装SDL库。在Linux系统上,可以使用以下命令:
sudo apt-get install libsdl2-dev
在Windows系统上,可以从SDL官方网站下载并安装。
#include <SDL2/SDL.h>
#include <stdio.h>
#include <math.h>
void draw_circle(SDL_Renderer *renderer, int x_center, int y_center, int radius) {
const int32_t diameter = (radius * 2);
int32_t x = (radius - 1);
int32_t y = 0;
int32_t tx = 1;
int32_t ty = 1;
int32_t error = (tx - diameter);
while (x >= y) {
// Each of the following renders an octant of the circle
SDL_RenderDrawPoint(renderer, x_center + x, y_center - y);
SDL_RenderDrawPoint(renderer, x_center + x, y_center + y);
SDL_RenderDrawPoint(renderer, x_center - x, y_center - y);
SDL_RenderDrawPoint(renderer, x_center - x, y_center + y);
SDL_RenderDrawPoint(renderer, x_center + y, y_center - x);
SDL_RenderDrawPoint(renderer, x_center + y, y_center + x);
SDL_RenderDrawPoint(renderer, x_center - y, y_center - x);
SDL_RenderDrawPoint(renderer, x_center - y, y_center + x);
if (error <= 0) {
++y;
error += ty;
ty += 2;
}
if (error > 0) {
--x;
tx += 2;
error += (tx - diameter);
}
}
}
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("SDL2 Circle",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
draw_circle(renderer, 320, 240, 100);
SDL_RenderPresent(renderer);
SDL_Delay(5000);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
解释代码
SDL_Init(SDL_INIT_VIDEO):初始化SDL视频子系统。SDL_CreateWindow:创建一个窗口。SDL_CreateRenderer:创建一个渲染器。SDL_SetRenderDrawColor:设置绘图颜色。draw_circle:函数使用Bresenham算法在给定的渲染器上绘制一个圆。SDL_RenderPresent:显示渲染结果。SDL_Delay:暂停程序,显示结果。
1.2 使用OpenCV库
OpenCV是一个广泛使用的计算机视觉库,也可以用于图像处理和绘图。在C语言中,可以使用OpenCV来绘制圆。
安装和初始化OpenCV库
在Linux系统上,可以使用以下命令:
sudo apt-get install libopencv-dev
在Windows系统上,可以从OpenCV官方网站下载并安装。
#include <opencv2/opencv.hpp>
#include <stdio.h>
int main() {
cv::Mat img = cv::Mat::zeros(480, 640, CV_8UC3);
cv::Point center(320, 240);
int radius = 100;
cv::Scalar color(0, 0, 255);
cv::circle(img, center, radius, color, 2);
cv::imshow("Circle", img);
cv::waitKey(0);
return 0;
}
解释代码
cv::Mat:创建一个空白图像。cv::Point:定义圆心位置。cv::circle:在图像上绘制圆。cv::imshow:显示图像。cv::waitKey:暂停程序,显示结果。
二、使用Bresenham算法
Bresenham算法是一种高效的圆形绘制算法,适用于没有图形库支持的情况。该算法利用整数运算,避免浮点计算,适合嵌入式系统。
2.1 基本原理
Bresenham算法基于对称性,只计算一个八分之一圆的像素点,然后利用对称性绘制其余部分。
2.2 实现代码
#include <stdio.h>
#include <stdlib.h>
void set_pixel(unsigned char* img, int width, int height, int x, int y, unsigned char color) {
if (x >= 0 && x < width && y >= 0 && y < height) {
img[y * width + x] = color;
}
}
void draw_circle(unsigned char* img, int width, int height, int x_center, int y_center, int radius, unsigned char color) {
int x = 0;
int y = radius;
int d = 3 - 2 * radius;
while (y >= x) {
set_pixel(img, width, height, x_center + x, y_center + y, color);
set_pixel(img, width, height, x_center - x, y_center + y, color);
set_pixel(img, width, height, x_center + x, y_center - y, color);
set_pixel(img, width, height, x_center - x, y_center - y, color);
set_pixel(img, width, height, x_center + y, y_center + x, color);
set_pixel(img, width, height, x_center - y, y_center + x, color);
set_pixel(img, width, height, x_center + y, y_center - x, color);
set_pixel(img, width, height, x_center - y, y_center - x, color);
x++;
if (d > 0) {
y--;
d = d + 4 * (x - y) + 10;
} else {
d = d + 4 * x + 6;
}
}
}
int main() {
int width = 640;
int height = 480;
unsigned char* img = (unsigned char*)malloc(width * height);
memset(img, 255, width * height);
draw_circle(img, width, height, 320, 240, 100, 0);
FILE* fp = fopen("circle.pbm", "wb");
fprintf(fp, "P5n%d %dn255n", width, height);
fwrite(img, 1, width * height, fp);
fclose(fp);
free(img);
return 0;
}
解释代码
set_pixel:函数设置像素点的颜色。draw_circle:函数使用Bresenham算法绘制圆。main:函数创建图像,调用draw_circle绘制圆,并保存为PBM格式。
三、其他绘制圆的方法
除了上述方法,还可以使用其他图形库或自定义算法进行绘制。
3.1 使用GDI库(Windows)
GDI(Graphics Device Interface)是Windows系统的图形设备接口,可以用于绘制图形。
#include <windows.h>
void draw_circle(HDC hdc, int x_center, int y_center, int radius) {
Ellipse(hdc, x_center - radius, y_center - radius, x_center + radius, y_center + radius);
}
int main() {
HWND hwnd = GetConsoleWindow();
HDC hdc = GetDC(hwnd);
draw_circle(hdc, 320, 240, 100);
ReleaseDC(hwnd, hdc);
return 0;
}
解释代码
GetConsoleWindow:获取控制台窗口句柄。GetDC:获取设备上下文(DC)。Ellipse:绘制椭圆。ReleaseDC:释放设备上下文。
3.2 使用自定义算法
可以根据需要自定义算法来绘制圆,例如使用参数方程。
#include <stdio.h>
#include <math.h>
void set_pixel(unsigned char* img, int width, int height, int x, int y, unsigned char color) {
if (x >= 0 && x < width && y >= 0 && y < height) {
img[y * width + x] = color;
}
}
void draw_circle(unsigned char* img, int width, int height, int x_center, int y_center, int radius, unsigned char color) {
for (int angle = 0; angle < 360; angle++) {
int x = x_center + radius * cos(angle * M_PI / 180);
int y = y_center + radius * sin(angle * M_PI / 180);
set_pixel(img, width, height, x, y, color);
}
}
int main() {
int width = 640;
int height = 480;
unsigned char* img = (unsigned char*)malloc(width * height);
memset(img, 255, width * height);
draw_circle(img, width, height, 320, 240, 100, 0);
FILE* fp = fopen("circle.pbm", "wb");
fprintf(fp, "P5n%d %dn255n", width, height);
fwrite(img, 1, width * height, fp);
fclose(fp);
free(img);
return 0;
}
解释代码
set_pixel:函数设置像素点的颜色。draw_circle:函数使用参数方程绘制圆。main:函数创建图像,调用draw_circle绘制圆,并保存为PBM格式。
四、总结
在C语言中绘制圆的方法多种多样,常用的方法包括:使用图形库、设置像素点、实现Bresenham算法。本文详细介绍了如何使用SDL库、OpenCV库和Bresenham算法在图片上绘制圆。通过这些方法,您可以根据具体需求选择合适的方案,完成在图片上绘制圆的任务。
热门推荐
从音质到性能:一文读懂车载音响评估要点
空调、座椅、音响:打造舒适车内环境的六大关键
中国极具潜力的养老小城:山水清秀,气候舒适,康养资源顶级
肇庆古城墙:千年砖石见证岭南历史
个人养老金理财扩容至26只,市场规模增长近3倍
消炎药vs抗生素:用药前必知的5大区别
阿莫西林怎么吃最好?饭后30分钟是关键
金线莲种植:农村致富新宠,年赚四十万不是梦!
金线莲:冬季养生的“百草之王”
金线莲:百草之王的养生密码
核桃Omega-3脂肪酸,护脑神器了解一下?
秋季养生神器:核桃的N种健康益处
从“出淤泥而不染”到“十里荷花香”:唐宋诗词里的莲花
核桃:心脏健康的秘密武器
核桃的营养成分揭秘:护脑效果有科学依据吗?
秋季吃河蟹,这些注意事项要知道!
国际青年打卡天津宁河大集,体验地道年味
天津之眼春节夜景攻略:120米高空俯瞰津城璀璨夜景
杨柳青年画里的天津年味
天津过年必打卡的五大特色景点
错过的白月光:洛芷与萧煜寒的悲剧爱情
唐代宗李豫:收复两京的权谋帝王
轻松洗净蒜苔:从冷水浸泡到牙刷刷洗
蒜苔选购保存全攻略:白帽品种更优
蒜苔营养价值揭秘:维C超水果,富含膳食纤维
亚麻仁油是什么?功效、副作用及常见问题全解析
机器学习模型评估神器:NMSE解析
晨明丁酸梭菌:守护肠道健康的益生菌
六味地黄丸:中医治疗口干的常用方剂
中医辨证论治,告别口渴口干烦恼