mfc_Paint_6 - 8BitsCoding/RobotMentor GitHub Wiki

ํŠน์ • ์˜์—ญ์„ ์„ ํƒํ•˜๋ฉด ์ƒ‰ ์ฑ„์šฐ๊ธฐ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ ์ž ํ•œ๋‹ค.

์ด๋ฏธ์ง€

// Dlg.h
// OnBnClickedFillRadio()
m_draw_wnd.SetDrawType(FILL_MODE);
// LBUTTONDOWN
if(m_draw_type == FILL_MODE) {
    int w = m_image.GetWidth(), h = m_image.GetHeight();
    COLORREF check_color = m_image_dc.GetPixel(point);  // ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ•œ ์ง€์ ์˜ ์ƒ‰์ƒ
    if(check_color == m_brush_color) return;
    m_image_dc.SetPixel(point, m_brush_color);
    ChangeColor(check_color, point.x, point.y, w, h);
    Invalidate();
} else {
    m_is_clicked = 1;
    m_prev_point = point;

    SetCapture();
}
// ChangeColor(COLORREF a_check_color, int a_x, int a_y, int a_width, int a_height)
{
    if(a_y - 1 >= 0) {
        if(m_image_dc.GetPixel(a_x, a_y - 1) == a_check_color) {
            m_image_dc.GetPixel(a_x, a_y - 1, m_brush_color);
            ChangeColor(a_check_color, a_x, a_y - 1, a_width, a_height);
        }
    }

    if(a_x + 1 >= 0) {
        if(m_image_dc.GetPixel(a_x + 1, a_y) == a_check_color) {
            m_image_dc.GetPixel(a_x + 1, a_y, m_brush_color);
            ChangeColor(a_check_color, a_x + 1, a_y, a_width, a_height);
        }
    }

    if(a_y + 1 >= 0) {
        if(m_image_dc.GetPixel(a_x, a_y + 1) == a_check_color) {
            m_image_dc.GetPixel(a_x, a_y + 1, m_brush_color);
            ChangeColor(a_check_color, a_x, a_y + 1, a_width, a_height);
        }
    }

    if(a_x - 1 >= 0) {
        if(m_image_dc.GetPixel(a_x - 1, a_y) == a_check_color) {
            m_image_dc.GetPixel(a_x - 1, a_y, m_brush_color);
            ChangeColor(a_check_color, a_x - 1, a_y, a_width, a_height);
        }
    }
}

ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒ

์žฌ๊ท€ํ˜ธ์ถœ ์ค‘ ์Šคํ…(๋””๋ฒ„๊ทธ ๋ชจ๋“œ ์‹œ 1MB) ์˜ค๋ฒ„ํ”Œ๋กœ๊ฐ€ ๋‚œ๋‹ค.

1ํ”ฝ์…€์— 4๋ฐ”์ดํŠธ * 1920 * 1080 FHD๋ผ๋ฉด ... ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ๊ณ ์•ˆํ•ด์•ผํ•œ๋‹ค.


์Šคํƒ ์˜ค๋ฒ„ํ”„๋กœ ๋•Œ๋ฌธ์— ์žฌ๊ท€ํ˜ธ์ถœ๋ง๊ณ  ๋ฐ˜๋ณต๋ฌธ์„ ์จ๋ณด์ž.

// LBUTTONDOWN
if(m_draw_type == FILL_MODE) {
    int w = m_image.GetWidth(), h = m_image.GetHeight();
    COLORREF check_color = m_image_dc.GetPixel(point);  // ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ•œ ์ง€์ ์˜ ์ƒ‰์ƒ
    if(check_color == m_brush_color) return;
    FillData * p_pixel_data = new FillData[w*h];
    memset(p_pixel_data, 0, sizeof(FillData)*w*h);
    m_image_dc.SetPixel(point, m_brush_color);

    FillData * p, * p_start = p_pixel_data, *p_add = p_pixel_data;
    p_add->x = (short)point.x;
    p_add->y = (short)point.y;
    p_add++;

    while(p_start != p_add) {
        p = p_start;
        while(p < p_add) {
            if(p->is_completed == 0) {

                if(p->y - 1 >= 0) {
                    if(m_image_dc.GetPixel(p->x, p->y - 1) == check_color) {
                        m_image_dc.GetPixel(p->x, p->y - 1, m_brush_color);
                        p_add->x = p->x;
                        p_add->y = p->y - 1;
                        p_add++;
                    }
                }

                if(p->x + 1 >= 0) {
                    if(m_image_dc.GetPixel(p->x + 1, p->y) == check_color) {
                        m_image_dc.GetPixel(p->x + 1, p->y, m_brush_color);
                        p_add->x = p->x + 1;
                        p_add->y = p->y;
                        p_add++;
                    }
                }

                if(p->y + 1 >= 0) {
                    if(m_image_dc.GetPixel(p->x, p->y + 1) == check_color) {
                        m_image_dc.GetPixel(p->x, p->y + 1, m_brush_color);
                        p_add->x = p->x;
                        p_add->y = p->y + 1;
                        p_add++;
                    }
                }

                if(p->x - 1 >= 0) {
                    if(m_image_dc.GetPixel(p->x - 1, p->y) == a_check_color) {
                        m_image_dc.GetPixel(p->x - 1, p->y, m_brush_color);
                        p_add->x = p->x - 1;
                        p_add->y = p->y;
                        p_add++;
                    }
                }

                p->is_completed = 1;
            }
            p++;
        }

        while(p_start < p_add) {
            if(p_start->is_completed == 0) break;
            p_start++;
        }
    }

    // ChangeColor(check_color, point.x, point.y, w, h);

    delete[] p_pixel_data;
    Invalidate();
} else {
    m_is_clicked = 1;
    m_prev_point = point;

    SetCapture();
}
struct FillData
{
    char is_completed;
    short x, y;
};

๋‹จ์ ์€ ์†๋„๊ฐ€ ๋งค์šฐ ๋А๋ฆฌ๋‹ค...


์†๋„๋ฅผ ๊ฐœ์„ ํ•ด๋ณด์ž.

// LBUTTONDOWN
if(m_draw_type == FILL_MODE) {
    int w = m_image.GetWidth(), h = m_image.GetHeight();

    BITMAP bmp_info;
    GetObject((HBITMAP)m_image, sizeof(BITMAP), &bmp_info);
    unsigned int * p_image = (unsigned int *)m_image.GetBits(), *p_check;
    p_image += bmp_info.bwWidthBytes / 4 - 1;
    // ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ์ ์œผ๋กœ ์ด๋™

    unsigned int check_color = *(p_image - point.y * w - (w - point.x - 1));
    // ์  ๋‹จ์œ„๋กœ ์ƒ‰์„ ์–ป๋Š”๋‹ค.

    unsigned int new_color = ((m_brush_color << 16) & 0x00FF0000) | (m_brush_color & 0x0000FF00) | (m_brush_color >> 16 & 0x000000FF);
    // Red์™€ Blue์˜ ์ƒ‰์ƒ์„ ๋ณ€๊ฒฝ
    // RGB ์นผ๋Ÿฌ์™€ CImage ์ปฌ๋Ÿฌ๋ฅผ ๋งž์ถ”๋Š” ๊ณผ์ •

    // ๊ทธ๋ฆผ์„ ์ฝ์œผ๋ฉด ํˆฌ๋ช…๋„๊ฐ€ 0xFF
    // Create ํ•จ์ˆ˜๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๋ฉด ํˆฌ๋ช…๋„๊ฐ€ 0x00
    new_color = new_color | (check_color & 0xFF000000);
    
    *(p_image - point.y * w - (w - point.x - 1)) = new_color;

    if(check_color == new_color) return;

    // COLORREF check_color = m_image_dc.GetPixel(point);  // ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ•œ ์ง€์ ์˜ ์ƒ‰์ƒ
    // if(check_color == m_brush_color) return;

    FillData * p_pixel_data = new FillData[w*h];
    memset(p_pixel_data, 0, sizeof(FillData)*w*h);
    m_image_dc.SetPixel(point, m_brush_color);

    FillData * p, * p_start = p_pixel_data, *p_add = p_pixel_data;
    p_add->x = (short)point.x;
    p_add->y = (short)point.y;
    p_add++;

    while(p_start != p_add) {
        p = p_start;
        while(p < p_add) {
            if(p->is_completed == 0) {
                p_check - p_image - p->y * w - (w - p->x - 1);

                if(p->y - 1 >= 0) {
                    if(*(p_check + w) == check_color) {
                        *(p_check + w) = new_color;
                        p_add->x = p->x;
                        p_add->y = p->y - 1;
                        p_add++;
                    }
                }

                if(p->x + 1 >= 0) {
                    if(*(p_check - 1) == check_color) {
                        *(p_check - 1) = new_color;
                        p_add->x = p->x + 1;
                        p_add->y = p->y;
                        p_add++;
                    }
                }

                if(p->y + 1 >= 0) {
                    if(*(p_check - w) == check_color) {
                        *(p_check + w) = new_color;
                        p_add->x = p->x;
                        p_add->y = p->y + 1;
                        p_add++;
                    }
                }

                if(p->x + 1 >= 0) {
                    if(*(p_check - 1) == check_color) {
                        *(p_check - 1) = new_color;
                        p_add->x = p->x - 1;
                        p_add->y = p->y;
                        p_add++;
                    }
                }

                p->is_completed = 1;
            }
            p++;
        }

        while(p_start < p_add) {
            if(p_start->is_completed == 0) break;
            p_start++;
        }
    }

    // ChangeColor(check_color, point.x, point.y, w, h);

    delete[] p_pixel_data;
    Invalidate();
} else {
    m_is_clicked = 1;
    m_prev_point = point;

    SetCapture();
}

ํ”ฝ์…€์„ ์ง์ ‘์ œ์–ดํ•จ์œผ๋กœ์„œ ์†๋„๋ฅผ ํ™•์‹คํ•˜๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.