在位图图像中绘制“from-to”

时间:2014-05-15 12:51:08

标签: c bitmap line

我们知道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的行,它们的结果很接近但不完全。

3 个答案:

答案 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相同。那就是问题

enter image description here

答案 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。它还有扩展来处理抗锯齿。