鱼C论坛

 找回密码
 立即注册
查看: 1171|回复: 9

[已解决]求解用数组和动态数组来画比特地图问题(bitmap)

[复制链接]
发表于 2019-11-5 08:58:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 丶不离不弃 于 2019-11-6 10:32 编辑

最近老师布置了一个有加分的题目就是让我们用C++来画bitmap,老师的要求如下:
int main() {
    // FIRST PART (ADD COLORS HERE)
    constexpr uint32_t BLACK = 0xFF000000; // black opaque
    constexpr uint32_t RED =   0xFF0000FF; // red opaque
    constexpr uint32_t BLUE =  0xFFFF0000;//blue opaque
    constexpr uint32_t WHITE = 0xFF0000FF;
    constexpr uint32_t YELLOW =   0xFF0000FF;

    // SECOND PART (DO NOT EDIT)
    int xcenter = 100;
    int ycenter = 100;
    int xdiameter = 200;
    int ydiameter = 100;
    Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)
    b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
    b.vertLine(0, 399, 300, RED); // Red vertical line, from y=0 to y=399, at x = 300
    b.drawRect(200,200, 100,50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
    b.fillRect(201,201, 98,48, WHITE); // White rectangle, same rules as above, but filled with color
    b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    b.ellipse(xcenter, ycenter, xdiameter, ydiameter); //Ellipse using specs from above
    b.save("bitmap.png");
    // THIRD PART - OPTIONAL FUNCTION
    // 100pt bonus for properly implementing Wu's antialiasing
    //https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
    //b.antialiasedLine(400,0, 550,300, YELLOW);
}

老师要求我们写的程序中要有头文件,我在github找了半天找到了个,但是我编译了一下有错https://github.com/StevensDeptEC ... b/stb_image_write.h
然后我写的程序部分就是用布雷森汉姆直线画法以及画椭圆部分不是特别明白,请问有大神可以帮我解决一下吗?谢谢!
我的代码如下:
#include <iostream>
#include <cmath>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <cstdint>
using namespace std;
#include "stb_image_write.h"
#include "stb.image.h"
#define x0 400       //定义全局变量x0,y0:坐标轴中心(x0,y0)
#define y0 300
class Bitmap{
private:
    constexpr static uint32_t w=800;
    constexpr static uint32_t h=600;
    uint32_t pixels[w][h];
public:
    Bitmap(uint32_t v){
        for(uint32_t i=0; i<h; i++){
            for(uint32_t j=0; j<w; j++){
                pixels[i][j]=v;
            }
        }
    }
    void horizLine(uint32_t x1, uint32_t x2, uint32_t y, uint32_t v) {
        for (uint32_t i = x1; i <= x2; i++) {
            pixels[y][i]=v;
        }
    }
    void vertLine(uint32_t y1, uint32_t y2, uint32_t x, uint32_t v){
        for(uint32_t j=y1; j<=y2; j++){
            pixels[j][x]=v;
        }
    }
    void fillRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
        for(uint32_t i=y; i<=y+h; i++){
            for(uint32_t j=x; j<=x+w; j++){
                pixels[i][j]=v;
            }
        }
    }
    void drawRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
        for(uint32_t i=y; i<=y+w; i++){
            pixels[x][i]=v;
            pixels[x+h][i]=v;
        }
        for(uint32_t j=x; j<=x+h; j++){
            pixels[j][y]=v;
            pixels[j][y+w]=v;
        }
    }
    void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v) {
        /*
        int Dx = x2 - x1;
        int Dy = y2 - y1;
        bool flag = false;
        if (abs(Dy) > abs(Dx)) {
            flag = true;
        }
        if (flag) {
            swap(x1, y1);
            swap(x2, y2);
        }
        if (x1 > x2) {
            swap(x1, x2);
            swap(y1, y2);
        }
        Dx = x2 - x1;
        int a = y2 - y1;
        Dy = abs(a);
        int Er = Dx / 2;
        double Der = Dy / Dx;
        int Ystep;
        int endy = y1;
         */
        int dx=x2-x1;//gain x
        int dy=y2-y1;//gain y
        int q=(2*dy)-dx;
        int doubleDy=2*dy;
        int doubleD=2*(dy-dx);
        int pointx;
        int pointy;
        //set two variable to display position
        if(x1>x2){
            pointx=x2;
            pointy=y2;
            x2=x1;
        }
        else{
            pointx=x1;
            pointy=y1;
        }
        while(pointx<x2){
            pointx++;
            if(q<0){
                q+=doubleDy;
            }
            else{
                pointy++;
                q+=doubleD;
            }
            for(uint32_t i=x1;i<=x2; i++){
                for(uint32_t j=y1; j<=y2;j++){
                    pixels[i][j]=v;
                }
            }
        }
    }


    void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v) {
        int X;
        int Y;
        int a = xdiameter / 2;
        int b = ydiameter / 2;
        const double PI = 3.14;
        double del = 0.001;
        for (double i = -PI; i < PI; i = i + del) {
            Y = ycenter + b * sin(i);
            X = xcenter + a * cos(i);
            pixels[Y][X] = v;
        }
    }


    void save(const char filename[]) {
        stbi_write_png(filename, w, h, 4, pixels, w*4);
    }

};

int main() {
    // FIRST PART (ADD COLORS HERE)
    constexpr uint32_t BLACK = 0xFF000000; // black opaque
    constexpr uint32_t RED =   0xFF0000FF; // red opaque
    constexpr uint32_t BLUE =  0xFFFF0000;//blue opaque
    constexpr uint32_t WHITE = 0xFF0000FF;
    constexpr uint32_t YELLOW =0xFF0000FF;
    constexpr uint32_t GREEN =0xFF0000FF;


    // SECOND PART (DO NOT EDIT)
    int xcenter = 100;
    int ycenter = 100;
    int xdiameter = 200;
    int ydiameter = 100;
    Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)
    b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
    b.vertLine(0, 399, 300, RED); // Red vertical line, from y=0 to y=399, at x = 300
    b.drawRect(200,200, 100,50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
    b.fillRect(201,201, 98,48, WHITE); // White rectangle, same rules as above, but filled with color
    b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    b.ellipse(xcenter, ycenter, xdiameter, ydiameter,GREEN); //Ellipse using specs from above
    b.save("bitmap.png");
    // THIRD PART - OPTIONAL FUNCTION
    // 100pt bonus for properly implementing Wu's antialiasing
    //https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
    //b.antialiasedLine(400,0, 550,300, YELLOW);
}




此外我还有如下问题:

1.下面这部分代码是用二维数组来做的,直线画法中如果用吴晓琳直线画法有额外的加分,但是我看了很久都不是特别会。

2.老师还有个建议是用动态数组来做,这个我到现在还没头绪,请问有人能教下我咋写的吗?老师上课的例子如下:
#include <iostream>
#include <cstdint>
using namespace std;
class Bitmap {
private:
    uint32_t w, h;
    uint32_t* b;
public:
    Bitmap(uint32_t w, uint32_t h, uint32_t pixel)
            : w(w), h(h), b(new uint32_t[w*h])
    {
        for (uint32_t i = 0; i < w*h; i++)
            b[i] = pixel;
    }
    Bitmap() : w(0), h(0), b(nullptr) {}
    ~Bitmap() {
        delete [] b;
    }
    Bitmap(const Bitmap& orig) :
            w(orig.w), h(orig.h), b(new uint32_t[orig.w*orig.h]) {
        memcpy(b, orig.b, sizeof(uint32_t) * w * h);
    }
#if 0
    this is the old way!!
    Bitmap& operator =(const Bitmap& orig) {
                if (this != &orig) {
                        delete [] b;
                        w = orig.w;
                        h = orig.h;
                        b = new uint32_t[w*h];
                        memcpy(b, orig.b, sizeof(uint32_t) * w * h);
                }
                return *this;
        }
#endif
    //modern approach: copy and swap
    Bitmap& operator =(Bitmap orig) {
        w = orig.w;
        h = orig.h;
        swap(b, orig.b);
        return *this;
    }
    Bitmap(Bitmap&& orig) : w(orig.w), h(orig.h), b(orig.b) {
        orig.b = nullptr;
    }
};
Bitmap makemeapicture() {
    Bitmap b(1024, 768, 0x0);
    return b;
}
int main() {
    Bitmap b(100,200, 0xFF000000);
    Bitmap b2(b); //copy constructor
    Bitmap b3(150,100, 0xFFFF);
    b3 = b2;
    b3 = b3;
    b2 = b3 = b;
}
最佳答案
2019-11-7 15:14:28
本帖最后由 superbe 于 2019-11-7 15:18 编辑

一些修改
    void fillRect(uint32_t x, uint32_t y,uint32_t w, uint32_t h, uint32_t v){
        /*for(uint32_t i=x; i<=y+h; i++){
            for(uint32_t j=y; j<= x+w; j++){
                m[i*j]=v;
            }
        }*/
        for(uint32_t i = x; i <= x + w; i++)
            for(uint32_t j = y; j <= y + h; j++){
                m[i + j * cols] = v;
            }
        
    }

    /* 这个函数有问题,画出的线位置不对,两个程序的line代码都改掉。参考Bresenham算法链接里的伪代码修改吧。 
       或参考我上面程序的line代码(也是照链接改的)。吴小林算法链接里也有伪代码,也照着编写吧。 */
    void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v){
          。。。
    }

    void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v){
            uint32_t X;
            uint32_t Y;
            uint32_t  a = xdiameter / 2;
            uint32_t b = ydiameter / 2;
            const double PI = 3.14;
            double del = 0.001;
            for (double i = -PI; i < PI; i = i + del) {
                Y = ycenter + b * sin(i);
                X = xcenter + a * cos(i);
                //m[Y*rows+X] = v;  //这行不对,改成下行
                m[Y * cols + X] = v;
            }
    }
    void save(const char filename[]) {
        //stbi_write_png(filename, rows, cols, 4, m, rows*cols * 4);
        stbi_write_png(filename, cols, rows, 4, m, cols * 4);
    }

修改后运行测试,只有line画线不正确。

head file.rar

75.7 KB, 下载次数: 4

这是2个头文件

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-6 12:53:05 | 显示全部楼层
顶一下~~~5555竟然木有人回答~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-6 13:49:42 | 显示全部楼层
比特地图是什么鬼?!那玩意不是叫 位图 吗?.bmp 格式的文件。
注意:我就是来吐个槽的,不要找我讨论问题的解答,没学多细致。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-7 00:03:23 | 显示全部楼层
本帖最后由 superbe 于 2019-11-7 21:12 编辑
#include <iostream>
#include <cmath>
#include <cstdint>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include "stb_image.h"
#define x0 400       //定义全局变量x0,y0:坐标轴中心(x0,y0)
#define y0 300
using namespace std;

class Bitmap{
private:
    constexpr static uint32_t w = 800;
    constexpr static uint32_t h = 600;
   uint32_t pixels[h][w];
public:
    Bitmap(uint32_t v){
        for (int i = 0; i < h; i++)
            for(int j = 0; j < w; j++)
                pixels[i][j] = v;
    }

    void horizLine(int x1, int x2, int y, uint32_t v) {
        for (int i = x1; i <= x2; i++) {
            pixels[y][i] = v;
        }
    }

    void vertLine(int y1, int y2, int x, uint32_t v){
        for(int j = y1; j <= y2; j++){
            pixels[j][x] = v;
        }
    }

    void fillRect(int x, int y, int w1, int h1, uint32_t v){
        for(int i = x; i <= x + w1; i++){
            for(int j = y; j <= y + h1; j++){
                pixels[j][i] = v;
            }
        }
    }

    void drawRect(int x, int y, int w1, int h1,uint32_t v){
        for(int i = x; i <= x + w1; i++){  //画两条水平线(可调用horizLine)
            pixels[y][i] = v;
            pixels[y + h1][i] = v;
        }
        for(int j = y; j <= y + h1; j++){  //画两条垂直线(可调用vertLine)
            pixels[j][x] = v;
            pixels[j][x + w1] = v;
        }
    }

    void line(int x1, int y1, int x2, int y2, uint32_t v){
        bool steep = abs(y2 - y1) > abs(x2 - x1);
        if(steep){
            swap(x1, y1);
            swap(x2, y2);
        }
        if(x1 > x2){
            swap(x1, x2);
            swap(y1, y2);
        }
        int deltax = x2 - x1;
        int deltay = abs(y2 - y1);
        int error = deltax / 2;
        int ystep = y1 < y2 ? 1 : -1;
        int y = y1;
        for(int x = x1; x <= x2; x++){
            if(steep) pixels[x][y] = v;
            else pixels[y][x] = v;
            error -= deltay;
            if(error < 0){
                y += ystep;
                error += deltax;
            }
        }
    }

    void ellipse(int xcenter, int ycenter, int xdiameter, int ydiameter, uint32_t v) {
        int x, y;
        int a = xdiameter / 2;
        int b = ydiameter / 2;
        const double PI = 3.14;
        double del = 0.001;
        for (double i = -PI; i < PI; i = i + del) {
            x = xcenter + a * cos(i);
            y = ycenter + b * sin(i);
            pixels[y][x] = v;
        }
    }

    void save(const char filename[]) {
        stbi_write_png(filename, w, h, 4, pixels, w * 4);
    }

};

int main() {
    //FIRST PART (ADD COLORS HERE)
    constexpr uint32_t BLACK = 0xFF000000; // black opaque
    constexpr uint32_t RED =   0xFF0000FF; // red opaque
    constexpr uint32_t BLUE =  0xFFFF0000; // blue opaque
    constexpr uint32_t WHITE = 0xFFFFFFFF;
    constexpr uint32_t YELLOW =0xFF00FFFF;
    constexpr uint32_t GREEN = 0xFF00FF00;

    // SECOND PART (DO NOT EDIT)
    int xcenter = 100;
    int ycenter = 100;
    int xdiameter = 200;
    int ydiameter = 100;
    Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)
    b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
    b.vertLine(0, 399, 300, RED);  // Red vertical line, from y=0 to y=399, at x = 300
    b.drawRect(200,200, 100, 50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
    b.fillRect(201,201, 98, 48, WHITE); // White rectangle, same rules as above, but filled with color
    b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    b.ellipse(xcenter, ycenter, xdiameter, ydiameter,GREEN); //Ellipse using specs from above
    b.save("bitmap3.png");
    // THIRD PART - OPTIONAL FUNCTION
    // 100pt bonus for properly implementing Wu's antialiasing
    //https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
    //b.antialiasedLine(400,0, 550,300, YELLOW);
}

如果编译提示stb_image_write.h第1696行错误,把该处
#define stbiw__zlib_add(code,codebits) \

      (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
中间的空行删掉就可以了。
吴小林直线画法待补充。其它的调试通过了。
你详细测试下吧,不确定有没有问题。
bitmap.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-11-7 03:57:12 | 显示全部楼层
本帖最后由 丶不离不弃 于 2019-11-7 03:59 编辑
superbe 发表于 2019-11-7 00:03
如果编译提示stb_image_write.h第1696行错误,把该处
#define stbiw__zlib_add(code,codebits) \

#include <iostream>
#include <cmath>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <cstdint>
#include "stb_imag.h"
#include "stb_imag_write.h"
using namespace std;
class Bitmap{
private:
    constexpr static uint32_t w=800;
    constexpr static uint32_t h=600;
    uint32_t pixels[h][w];
public:
    Bitmap(uint32_t v){
        for(uint32_t i=0; i<h; i++){
            for(uint32_t j=0; j<w; j++){
                pixels[i][j]=v;
            }
        }
    }
    void horizLine(uint32_t x1, uint32_t x2, uint32_t y, uint32_t v) {
        for (uint32_t i = x1; i <= x2; i++) {
            pixels[y][i]=v;
        }
    }
    void vertLine(uint32_t y1, uint32_t y2, uint32_t x, uint32_t v){
        for(uint32_t j=y1; j<y2; j++){
            pixels[j][x]=v;
        }
    }
    void fillRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
        for(uint32_t i=y; i<=y+h; i++){
            for(uint32_t j=x; j<=x+w; j++){
                pixels[i][j]=v;
            }
        }
    }
    void drawRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
        for(uint32_t i=y; i<=y+w; i++){
            pixels[x][i]=v;
            pixels[x+h][i]=v;
        }
        for(uint32_t j=x; j<=x+h; j++){
            pixels[j][y]=v;
            pixels[j][y+w]=v;
        }
    }
    void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v) {
        int x, y, dx, dy, e;
        dx = x2 - x1;
        dy = y2 - y1;
        e = -dx;
        x = x1;
        y = y1;
        for (int i = 0; i <= dx; i++) {
            pixels[y][x] = v;
            x++;
            e = e + 2 * dy;
            if (e >= 0) {
                y++;
                e = e - 2 * dx;
            }
        }
    }


    void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v) {
        int X;
        int Y;
        int a = xdiameter / 2;
        int b = ydiameter / 2;
        const double PI = 3.14;
        double del = 0.001;
        for (double i = -PI; i < PI; i = i + del) {
            Y = ycenter + b * sin(i);
            X = xcenter + a * cos(i);
            pixels[Y][X] = v;
        }
    }


    void save(const char filename[]) {
        stbi_write_png(filename, w, h, 4, pixels, w*4);
    }

};

int main() {
    // FIRST PART (ADD COLORS HERE)
    constexpr uint32_t BLACK = 0xFF000000; // black opaque
    constexpr uint32_t RED =   0xFF0000FF; // red opaque
    constexpr uint32_t BLUE =  0xFFFF0000;//blue opaque
    constexpr uint32_t WHITE = 0xFFFFFFFF;//white opaque
    constexpr uint32_t YELLOW =0xFF00FFFF;//yellow opaque
    constexpr uint32_t GREEN = 0xFF008000;//green opaque


    // SECOND PART (DO NOT EDIT)
    int xcenter = 100;
    int ycenter = 100;
    int xdiameter = 200;
    int ydiameter = 100;
    Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)

    b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
    b.vertLine(0, 399, 300, RED); // Red vertical line, from y=0 to y=399, at x = 300
    b.drawRect(200,200, 100,50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
    b.fillRect(201,201, 98,48, WHITE); // White rectangle, same rules as above, but filled with color
    b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    b.ellipse(xcenter, ycenter, xdiameter, ydiameter,GREEN); //Ellipse using specs from above
    b.save("bitmap.png");
    // THIRD PART - OPTIONAL FUNCTION
    // 100pt bonus for properly implementing Wu's antialiasing
    //https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
    //b.antialiasedLine(400,0, 550,300, YELLOW);
}
这是我自己画的哈哈,和你的一样哈哈!!我在你之前做出来了哈啊哈,开心!不过还是要谢谢你呢!
现在就是另一个问题就是老师说的拓展写法用动态数组来画~~~我感觉还是一片空白~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-7 04:03:36 | 显示全部楼层
本帖最后由 丶不离不弃 于 2019-11-7 04:15 编辑
superbe 发表于 2019-11-7 00:03
如果编译提示stb_image_write.h第1696行错误,把该处
#define stbiw__zlib_add(code,codebits) \


我现在在纠结如何用动态数组new int【】来画,就是我后面发的老师给的那个范例,包括用move 构造器,复制(=)构造器等等。你可以帮我看一下嘛~~谢谢。老师说的用吴晓琳画法是在用dynamic memory 方法来写的bitmap加分项目。我今天下午研究下然后尽量在你们起床前发到论坛上我的程序。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-7 06:36:29 | 显示全部楼层
superbe 发表于 2019-11-7 00:03
如果编译提示stb_image_write.h第1696行错误,把该处
#define stbiw__zlib_add(code,codebits) \
#include <cstdint>
#include <iostream>
#include<math.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_imag.h"
#include "stb_imag_write.h"
#include <cmath>
using namespace std;
class dynamicBitmap{
private:
    uint32_t *m;
    uint32_t cols,rows;
public:
    dynamicBitmap(uint32_t r, uint32_t c,uint32_t v):rows(r),cols(c),m(new uint32_t [r*c]){
        for(uint32_t i=0; i<r*c; i++){
            m[i]=v;
        }
    }
    ~dynamicBitmap(){
        delete [] m;
    }
    dynamicBitmap(const dynamicBitmap& copy)
            :rows(copy.rows),cols(copy.cols),m(new uint32_t[copy.rows*copy.cols]){
        memcpy(m,copy.m,sizeof(uint32_t)*rows*cols);
    }
    /*
    //old way
    dynamicBitmap& operator=(const dynamicBitmap& orig){
        if(this != &orig){
            delete[] m;
            rows=orig.rows;
            cols=orig.cols;
            m= new uint32_t[rows*cols];
            memcpy(m,orig.m, sizeof(uint32_t)*rows*cols);
            return *this;
        }
    }
    */

    /*new way*/
    dynamicBitmap& operator=(dynamicBitmap orig){
        cols=orig.cols;
        rows=orig.rows;
        swap(m,orig.m);
        //memcpy(m,orig.m, sizeof(uint32_t)*rows*cols);
        return *this;
    }

    /*move constructor*/
    dynamicBitmap(dynamicBitmap&& orig):rows(orig.rows),cols(orig.cols),m(orig.m){
        orig.m=nullptr;
    }

    void horizLine(uint32_t x1, uint32_t x2, uint32_t y, uint32_t v){
        for(uint32_t i=x1; i<=x2; i++){
            m[y*cols+i]=v;
        }
    }
    void vertLine(uint32_t y1, uint32_t y2, uint32_t x, uint32_t v){
        for(uint32_t j=y1; j<=y2; j++){
            m[j*cols+x]=v;
        }
    }
    void drawRect(uint32_t x, uint32_t y,uint32_t w, uint32_t h, uint32_t v){
        for(uint32_t i=x;i <=x+w; i++){
            m[y*cols+i]=v;
            m[(y+h)*cols+i]=v;
        }
        for(uint32_t j=y; j<=y+h; j++){
            m[j*cols+x]=v;
            m[j*cols+(x+w)]=v;
        }
    }

    void fillRect(uint32_t x, uint32_t y,uint32_t w, uint32_t h, uint32_t v){
        for(uint32_t i=x; i<=y+h; i++){
            for(uint32_t j=y; j<= x+w; j++){
                m[i*j]=v;
            }
        }
    }

    void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v){
        int x, y, dx, dy, e;
        dx = x2 - x1;
        dy = y2 - y1;
        e = -dx;
        x = x1;
        y = y1;
        for (int i = 0; i <= dx; i++) {
            m[y*x] = v;
            x++;
            e = e + 2 * dy;
            if (e >= 0) {
                y++;
                e = e - 2 * dx;
            }
        }
    }

    void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v){
            uint32_t X;
            uint32_t Y;
            uint32_t  a = xdiameter / 2;
            uint32_t b = ydiameter / 2;
            const double PI = 3.14;
            double del = 0.001;
            for (double i = -PI; i < PI; i = i + del) {
                Y = ycenter + b * sin(i);
                X = xcenter + a * cos(i);
                m[Y*rows+X] = v;
            }
    }
    void save(const char filename[]) {
        stbi_write_png(filename, rows, cols, 4, m, rows*cols * 4);
    }


};


int main() {
    // FIRST PART (ADD COLORS HERE)
    constexpr uint32_t BLACK = 0xFF000000; // black opaque
    constexpr uint32_t RED = 0xFF0000FF; // red opaque
    constexpr uint32_t BLUE = 0xFFFF0000; // blue opaque
    constexpr uint32_t WHITE = 0xFFFFFFFF; // white opaque
    constexpr uint32_t YELLOW = 0xFF00FFFF; // yellow opaque
    constexpr uint32_t GREEN = 0xFF00FF00; // green opaque

    // SECOND PART (DO NOT EDIT)
    int xcenter = 100;
    int ycenter = 100;
    int xdiameter = 200;
    int ydiameter = 100;

    dynamicBitmap b(1024, 1024, BLACK); // Potentially dynamic size (Now: 1024 x 1024 pixels)

    b.horizLine(0, 500, 200, RED); // horizontal line from x=0 to x=500, @y = 200
    b.vertLine(0, 399, 300, RED); // y=0 to y=399 @ x= 300, red vertical line
    b.drawRect(200,200, 100,50, BLUE); // blue rectangle, top-left=200,200 w=100 h=50
    b.fillRect(201,201, 98,48, WHITE); // same but filled
    b.line(400,0, 550,300, YELLOW); // draw a line https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
    b.ellipse(xcenter, ycenter, xdiameter, ydiameter,YELLOW);
    b.save("bitmap.png");

}
第二种方法用dynamicbitmap 来做然后我写了,编译也没错,但是为啥出不了png的图呀,请问你可以帮我看看哪里有问题吗?很奇怪,还有我在draw 和fillrect的时候感觉行和列有点问题,你可以帮我看一下吗,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-7 15:14:28 | 显示全部楼层    本楼为最佳答案   
本帖最后由 superbe 于 2019-11-7 15:18 编辑

一些修改
    void fillRect(uint32_t x, uint32_t y,uint32_t w, uint32_t h, uint32_t v){
        /*for(uint32_t i=x; i<=y+h; i++){
            for(uint32_t j=y; j<= x+w; j++){
                m[i*j]=v;
            }
        }*/
        for(uint32_t i = x; i <= x + w; i++)
            for(uint32_t j = y; j <= y + h; j++){
                m[i + j * cols] = v;
            }
        
    }

    /* 这个函数有问题,画出的线位置不对,两个程序的line代码都改掉。参考Bresenham算法链接里的伪代码修改吧。 
       或参考我上面程序的line代码(也是照链接改的)。吴小林算法链接里也有伪代码,也照着编写吧。 */
    void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v){
          。。。
    }

    void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v){
            uint32_t X;
            uint32_t Y;
            uint32_t  a = xdiameter / 2;
            uint32_t b = ydiameter / 2;
            const double PI = 3.14;
            double del = 0.001;
            for (double i = -PI; i < PI; i = i + del) {
                Y = ycenter + b * sin(i);
                X = xcenter + a * cos(i);
                //m[Y*rows+X] = v;  //这行不对,改成下行
                m[Y * cols + X] = v;
            }
    }
    void save(const char filename[]) {
        //stbi_write_png(filename, rows, cols, 4, m, rows*cols * 4);
        stbi_write_png(filename, cols, rows, 4, m, cols * 4);
    }

修改后运行测试,只有line画线不正确。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-9 20:46:56 | 显示全部楼层
第二个程序的完整代码,仅供参考
main.rar (2.49 KB, 下载次数: 0)

其中changeColor函数我只是简单的把r g b每个分量都同等的乘以亮度(0<=brightness<=1),应该有更合理的方法。
但测试antialiasedLine的效果还是可以的,你多画几条线放大看有边缘虚化的效果。

有的代码是参考网上的,我也看不太懂。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-10 22:31:16 | 显示全部楼层
superbe 发表于 2019-11-9 20:46
第二个程序的完整代码,仅供参考


好的谢谢啦!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 12:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表