working with pixels

I'm trying to draw a horizontal line at the bottom and then create two horizontal lines diagonal creating an equal lateral triangle but I can only make a horizontal line at the top and a vertical line on the left how could I access certain parts of the vector so I know which pixels I'm changing?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  #include <cstdint>
#include <iostream>
#include <vector>
 
int main() {
  constexpr int w = 300;
  constexpr int h = 200;
  std::vector<uint32_t> draw_line(w * h);
  for (int x = 0; x < w; ++x) {
    draw_line[x] = 0xffff0000 | 0 | 0 | 0 << 16;
    for (int y = 0; y < h; ++y) {
      draw_line[w * y] = 0xffff0000 | 0 | 0 << 16;
    }
  }
  std::cout.write(reinterpret_cast<char *>(draw_line.data()), w * h * 4);
Last edited on
draw_line[desired_row*number_of_colums + desired column]
in your code that is
draw_line[somerow*w+somecol]

and you need to either use triangle magic math or the equations of the lines to find the rows and cols you need to mark.

it looks like ascii art, not pixels... in which case make draw_line unsigned char and just put an '*' in there until you get it working, spaces for unused locations. The ors with zero don't do anything (0s remain 0s, 1s remain 1s). ??
Last edited on
it is RGBA trying to figure out how to change the bottom part and create a pixel of lines but I just get errors which just turn the picture black
Last edited on
what errors?
Simplify it, I edited my post... just try to draw characters for now.
when I pipe output into convert -depth 8 -size 300x200 rgba:~/public_html/test.png
I get the error
convert-im6.q16: unexpected end-of-file `-': No such file or directory @ error/rgb.c/ReadRGBImage/239.
what do you get from this:

uint32_t test=0xffff0000 | 0 | 0 << 16;
cout << test << endl;

not sure about end of file. You write enough data, but does cout do anything odd with the unprintable characters? I would write it to a binary file and feed that file to your png generator. There are image editors that can open RGB or RGBA binary files as well, just have to type in the dimensions. I always just did it that way and saved them as whatever type from there, usually jpeg.

if you are not getting anywhere, try this:
programname > filename
and use a hex editor on filename to see what you are actually getting.
Last edited on
I get 4294901760 I trying it by just setting the spaces to a number from the x direction and from the y direction then cout so I can pin point which pixels places I need to change, you think this is a good idea?
Show the exact command pipe. How do you specify the input file to convert? Do you use a dash? Does convert accept a dash in the usual way (maybe it only reads from files)?
Last edited on
Maybe something like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <algorithm>
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <cstdint>

void putpixel(std::vector<uint32_t>& canvas, int width,
              int x, int y, uint32_t color) {
    canvas[y * width + x] = color;
}

void draw_line(std::vector<uint32_t>& canvas, int width,
               int x1, int y1, int x2, int y2, uint32_t color) {
    float dx = x2 - x1, dy = y2 - y1;
    int step = abs(dx) >= abs(dy) ? abs(dx) : abs(dy);
    dx /= step;
    dy /= step;
    float x = x1, y = y1;
    for (int i = 0; i < step; i++) {
        putpixel(canvas, width, int(x), int(y), color);
        x += dx;
        y += dy;
    }
}

void to_png(std::vector<uint32_t>& canvas, int width, const char *filename) {
    std::string s {"convert -depth 8 -size "};
    s += std::to_string(width) + 'x' + std::to_string(canvas.size() / width);
    s += " rgba:- ";
    s += filename;
    FILE *p = popen(s.c_str(), "w");
    fwrite(reinterpret_cast<char *>(canvas.data()), 1, canvas.size() * 4, p);
    pclose(p);
}

int main() {
    const int width = 300, height = 200;
    std::vector<uint32_t> canvas(width * height);
    std::fill(canvas.begin(), canvas.end(), 0xff000000);

    std::default_random_engine rng(std::random_device{}());
    int x = rng() % width, y = rng() % height;
    for (int i = 0; i < 30; i++) {
        int x2 = rng() % width, y2 = rng() % height;
        draw_line(canvas, width, x, y, x2, y2, 0xff000000 + rng() % 0x1000000);
        x = x2; y = y2;
    }

    to_png(canvas, width, "out.png");
}

Last edited on
Topic archived. No new replies allowed.