참고 링크: https://www.youtube.com/watch?v=e6ivB-FQo_k&list=PLlIX4lkC1JdMx-vfK8I-J3-L-GL7TbMf9&index=11&pp=iAQB
초기값 어둡게 하기
변경한 부분
0으로 변경
memset(fm, 0, nWidth * nHeight);
밝기 부분 255로 나눠주기
// 점찍기
for (int k = 0; k < 100; k++) {
int x = rand() % nWidth;
int y = rand() % nHeight;
fm[y * nPitch + x] = rand()%0xff; // 각각의 밝기에 대해서 255(0xff)로 나눠준다.
}
좌표의 픽셀 값이 0이 아닐 경우로 바꿔주기
if (fm[j * nPitch + i] != 0)
// 찍힌 점의 좌표를 m_ptData 배열에 저장
// 모든 픽셀을 탐지하기 위한 이중 for문: 너비만큼, 높이만큼 반복: (i, j)는 픽셀의 (x, y)에 해당
for (int j = 0; j < nHeight;j++) {
for (int i = 0; i < nWidth; i++) {
if (fm[j * nPitch + i] != 0) { // 좌표의 픽셀 값이 0인지(점이 찍혀 있는지) 확인
// 찍힌 점을 찾았다면, 그 점의 좌표를 m_ptData 배열에 저장함
if (m_pDlgImgResult->m_nDataCount <= 100) { // 먼저 m_nDataCount가 100 이하인지 확인(배열의 크기가 100이므로)
m_pDlgImgResult->m_ptData[nIndex].x = i; // 찾은 점의 x 좌표를 배열에 저장
m_pDlgImgResult->m_ptData[nIndex].y = j; // 찾은 점의 y 좌표를 배열에 저장
// m_nDataCount 값을 1씩 증가시키며, 동시에 nIndex값을 1 증가시킨다. (++nIndex의 결과는 nIndex 증가 후의 값이므로)
m_pDlgImgResult->m_nDataCount = ++nIndex;
}
}
}
}
실행시켜 보면 왼쪽 화면이 검게 나오는 것을 확인할 수 있다.
흰 점들이 포인터들로 만들어져 있고, 밝기에 따라 다르지만 점이 찍힌걸 확인할 수 있다.
몇 개의 점이 찍혀있는지 확인해 보자.
cout << nIndex << ":" << i << "," << j << endl;
if문 안에 위 코드를 넣으면 몇개의 좌표가 찍혔는지 확인할 수 있다.
// 찍힌 점의 좌표를 m_ptData 배열에 저장
// 모든 픽셀을 탐지하기 위한 이중 for문: 너비만큼, 높이만큼 반복: (i, j)는 픽셀의 (x, y)에 해당
for (int j = 0; j < nHeight;j++) {
for (int i = 0; i < nWidth; i++) {
if (fm[j * nPitch + i] != 0) { // 좌표의 픽셀 값이 0인지(점이 찍혀 있는지) 확인
// 찍힌 점을 찾았다면, 그 점의 좌표를 m_ptData 배열에 저장함
if (m_pDlgImgResult->m_nDataCount <= 100) { // 먼저 m_nDataCount가 100 이하인지 확인(배열의 크기가 100이므로)
cout << nIndex << ":" << i << "," << j << endl; // 찍힌 점의 갯수 세기
m_pDlgImgResult->m_ptData[nIndex].x = i; // 찾은 점의 x 좌표를 배열에 저장
m_pDlgImgResult->m_ptData[nIndex].y = j; // 찾은 점의 y 좌표를 배열에 저장
// m_nDataCount 값을 1씩 증가시키며, 동시에 nIndex값을 1 증가시킨다. (++nIndex의 결과는 nIndex 증가 후의 값이므로)
m_pDlgImgResult->m_nDataCount = ++nIndex;
}
}
}
총 100개의 점이 찍혔다.
가로값을 줄이면 그 값들은 더 작아진다.
펜의 색을 디파인해서 사용해 보자.
#define COLOR_RED RGB(255, 0, 0)
#define COLOR_RED RGB(255, 0, 0)
을 함수 위에 선언해서 COLOR_RED를 숫자 대신 가져와서 사용할 수 있다.
적용전
pen.CreatePen(PS_SOLID, 5, RGB(0xff, 0, 0)); // 실선, 두께, 빨간색
적용후
pen.CreatePen(PS_SOLID, 5, COLOR_RED); // 실선, 두께, 빨간색
결과값은 똑같이 빨간색 점으로 그려진다.
drawData 함수에 CPen에 적용할 때 사용된 코드이다.
drawData 함수
*참고: Cpen 뒤에 붙은 *은 포인터를 나타낸다. CPen은 클래스 타입이며, *은 포인터 변수를 선언할 때 사용된다. CPen*은 CPen 객체를 가리키는 포인터 변수를 선언하는 것을 의미한다.
*포인터 사용 이유: 포인터를 사용하는 이유는 하나의 객체의 복사를 피하고 메모리를 효율적으로 관리할 수 있기 때문이다. 함수에 객체를 전달하면 복사본이 만들어지고, 객체가 크거나 복사 비용이 높을 경우 이를 피하기 위해 포인터를 사용한다.
*& 사용 이유: 해당 객체의 주소를 얻기 위함. & 연산자는 주소 연산자로, 변수나 객체의 주소를 반환한다.
drawData 함수
#define COLOR_RED RGB(255, 0, 0)
void CDlgImage::datwData(CDC* pDC)
{
CRect rect;
CPen pen; // 선 클래스 객체 생성
pen.CreatePen(PS_SOLID, 5, COLOR_RED); // 실선, 두께, 빨간색
CPen* pOldPen = pDC->SelectObject(&pen); // 현재 펜 저장(펜 객체의 주소를 pOldPen 포인터에 저장한다. 이렇게 하믕로써 팬 객체를 저장해두고 나중의 원래의 펜으로 복원할 수 있게 된다.)
for (int i = 0; i < m_nDataCount; i++) {
rect.SetRect(m_ptData[i], m_ptData[i]); // 좌표값 설정
rect.InflateRect(2, 2); // 좌로 2만큼, 우로 2만큼 벌린다
pDC->Ellipse(rect); //원을 그린다
}
pDC->SelectObject(pOldPen); // 저장해 둔 펜 가져오기
}
&와 *연산자 구분하기
&와 *는 서로 다른 역할을 하는 연산자이다.
1. & 연산자:
- 주소 연산자
- 변수나 객체의 주소를 얻기 위해 사용
- int x = 5; 같이 정수형 변수 x가 있다면, &x는 변수 x의 주소를 나타낸다.
2. * 연산자
- * 연산자는 간접 참조 연산자이며, 포인터를 통해 값을 읽거나 수정하는 데 사용된다.
- 포인터 변수를 선언할 때도 사용되며, 포인터 변수는 다른 변수나 객체의 주소를 저장할 수 있다.
- 예를 들어, int* ptr = &x;와 같이 정수형 포인터 변수 ptr을 선언하고, ptr을 통해 x의 값을 읽거나 수정할 수 있다. *ptr은 x의 값을 나타낸다.
int x = 5; int* ptr = &x; // ptr에 x의 주소를 저장 int y = *ptr; // ptr을 통해 x의 값을 읽어와서 y에 저장 *y = 10; // ptr을 통해 x의 값을 10으로 수정
이 예에서 & 연산자는 변수 x의 주소를 얻기 위해 사용되고, * 연산자는 포인터 ptr을 통해 x의 값을 읽거나 수정하기 위해 사용된다
아래와 같이 16진수로 rgb값을 표현할 수도 있다.
#define COLOR_RED RGB(0xff, 0x00, 0x00)
#define COLOR_GREEN RGB(0x00, 0xff, 0x00)
대문자 만들기 단축키
Shift + Ctrl + U
define 문은 기본적으로 mfc가 call 하는 클래스인 헤더 파일로 이동하여
정의하는 부분을 넣어주면 파일이 열리기 전에 초기화 된다.
이 내용이 길어지거나 무거우면 파일이 열리기 전에 컴파일 시간이 오래 걸릴 수 있으나
아래와 같은 색상 정의는 시간이 오래 걸리지 않으므로 여기에서는 패스한다.
DEFINE 부분은 여러 부분에서 사용할 수 있는데, 특히 변수 선언을 할 때는 숫자를 사용하지 않고 변수로 파라미터를 생성하여 넘겨줘야 가독성이 높아지고 유지보수가 편해지는 장점이 있다.
예: 100이라는 숫자를 MAX_POINT 변수에 저장하여 배열에 넣어줬다.
CTRL + SHIFT + F 를 사용하여 100을 사용한 부분을 찾아 위의 변수를 넣어주면 한번에 쉽게 바꿀 수 있다.
'개발공부 > C++' 카테고리의 다른 글
[C++] MFC 다이얼로그 중심에 원 그리기 (0) | 2023.09.20 |
---|---|
[C++] <chrono> 헤더 사용하여 함수 실행시간 측정 (0) | 2023.09.19 |
[C++] MFC 다른 윈도우로 포인트 복제하기 (1) | 2023.09.18 |
[C++] MFC 듀얼이미지 다이얼로그 (0) | 2023.09.18 |
[C++] MFC 모달리스 다이얼로그 생성하기 (0) | 2023.09.18 |