我们知道mspaint可以画成画面的直线。由于嵌套循环填充整个区域(x / y),我想知道这样做的方式。从图像的(x0 y0)绘制一条线到所需的x / y。我使用此函数来查找bmp的x / y像素:
dword find (FILE* fp, dword xp, dword yp)
{
word bpx = (3*8);
dword offset = (2+sizeof(BMP)+sizeof(DIB));
dword w = 500;
dword row = (((bpx * w) * 4) / 32);
dword pixAddress = (offset) + row * yp + ((xp * bpx) / 8);
return pixAddress;
}
我尝试使用许多函数绘制从0x0到xy的行,它们的结果很接近但不完全。
答案 0 :(得分:1)
byte color_pattern[] = { 255, 255, 255 };
dword xy_offset[] = {1, 1};
void bmp_lineto(dword endx, dword endy)
{
int dx = endx - xy_offset[0];
int dy = endy - xy_offset[1];
int twody = 2 * dy;
int twodxdy = 2 * (dy - dx);
int dp = twody - dx;
int X, Y, xEnd, yEnd;
FILE* fp = fopen(convert(FILENAME.text), "rb+");
if(xy_offset[0] > endx)
{
X = endx;
Y = endy;
xEnd = xy_offset[0];
}
else
{
X = xy_offset[0];
Y = xy_offset[1];
xEnd = endx;
}
while(X < xEnd)
{
X = X + 1;
if(dp < 0)
{
dp = dp + twody;
} else { Y = Y + 1; dp = dp + twodxdy;
}
fseek(fp, find(fp, X, Y), SEEK_SET);
fwrite(&color_pattern, 1, 3, fp);
}
}
但是这段代码中bmp的结果是如此......不确定:
bmp_lineto(200, 230);
整个图片为x500 : y460
更新。 y坐标与x相同。那就是问题
答案 1 :(得分:1)
看看下面的代码 - 我从Rosetta Code
改编了这个代码#include <stdio.h>
#include <stdlib.h>
#define NX 40
#define NY 20
typedef unsigned char byte;
typedef struct {
int x;
int y;
} point;
typedef struct{
char M[NX][NY];
} bitmap;
void drawLine(point *a, point*b, bitmap *B, FILE* fp, byte *color_pattern) {
int x0 = a->x, y0 = a->y;
int x1 = b->x, y1 = b->y;
int dx = abs(x1-x0), sx = (x0<x1) ? 1 : -1;
int dy = abs(y1-y0), sy = (y0<y1) ? 1 : -1;
int err = (dx>dy ? dx : -dy)/2, e2;
int index;
while(1){
// the next three lines put the pixel right in the file:
index = (y0 * NX + x0)*3;
fseek(fp, index, SEEK_SET);
fwrite(color_pattern, 1, 3, fp);
B->M[x0][y0]=1; // for code testing
if (x0==x1 && y0==y1) break;
e2 = err;
if (e2 >-dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
void printLine(bitmap *B){
int ii, jj;
for(ii=0; ii<NY; ii++) {
for(jj=0; jj<NX; jj++) {
printf("%d", (int)B->M[jj][ii]);
}
printf("\n");
}
}
int main(void) {
FILE *fp;
point start = {34,7};
point end = {14, 17};
bitmap B;
byte color[]={255,255,255};
// initialize map to zero. Want to do same with file I suppose
int ii, jj;
for(ii=0; ii<NX; ii++) {
for(jj=0; jj<NY; jj++) {
B.M[ii][jj]=0;
}
}
fp = fopen("mypicture.bmp", "wb");
drawLine(&start, &end, &B, fp, color);
printLine(&B);
fclose(fp);
}
我认为应该很容易适应你的情况。注意我试图将变量分开/本地化一点 - 这通常是一个好主意;还有很多方法可以进一步改进这段代码(这种情况下C ++可能是一种更好的语言......)
以上输出:
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000001100000
0000000000000000000000000000000110000000
0000000000000000000000000000011000000000
0000000000000000000000000001100000000000
0000000000000000000000000110000000000000
0000000000000000000000011000000000000000
0000000000000000000001100000000000000000
0000000000000000000110000000000000000000
0000000000000000011000000000000000000000
0000000000000001100000000000000000000000
0000000000000010000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
看起来像&#34;对&#34;对我来说......尽管它让X走向了负面的方向。这是从经过验证的代码开始的优势(在这种情况下,Bresenham的算法在Rosettacode上实现)。
答案 2 :(得分:0)
您可以查看Bresenham's line algorithm。它还有扩展来处理抗锯齿。