소연의_개발일지
article thumbnail

참고 링크: 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을 사용한 부분을 찾아 위의 변수를 넣어주면 한번에 쉽게 바꿀 수 있다.

 


 

profile

소연의_개발일지

@ssoyxon

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!