반응형

빠른 해결 방법은 아래로 내려가세요! 해결 방법

 

으윽 Visual Studio에서 QT로 프로젝트를 개발하는 도중에.. 한글이 깨지는 현상이 발견되었다..

그리고 한글을 쓴 상태에서 빌드를 해보니

오류 C2001 : 상수에 줄 바꿈 문자가 있습니다.	
오류 C2146 : 구문 오류: ')'이(가) 'M_FaceCount' 식별자 앞에 없습니다.
오류 C2146 : 구문 오류: ';'이(가) 'M_FaceCount' 식별자 앞에 없습니다.

뭐 이런식으로 오류가 떴다..

이게 문제인 것 같은데.. 난 분명 줄 바꿈 문자를 넣지도 않았는데 저래 뜬다..

그리고 겨우 빌드 해도..

이런식으로 알 수 없는 문자로 뜨는 것이다..

 

그래서 예전에 생각해보니 비슷한 문제가 있어 인코더 문제인가 하고 인코더를 바꿔보니 되는 것이다!

해결방법

문제가 일어나는 파일을 선택 후 "파일 > 다른 이름으로 이름.cpp 저장(A)..."

저장하는 파일 목록이 뜨면 아래에서 저장 바로 오른쪽에 아래로 내리는 삼각형 표시 클릭

그러면 이렇게 인코딩하여 저장(V)... 이 뜨는데 이걸 눌러야 합니다!

글고 파일을 바꿀껀지 묻는데 인코더를 바꿔야 함으로 당연히 바꾸기 클릭!

그럼 이런식으로 뜨는데 여기에서 인코딩이 보통 한국어 - 코드 페이지 949로 뜨는데 이걸 유니코드(서명 없는 UTF-8) - 코드 페이지 65001로 바꿉니다! (보통 Visual Studio에서 저장하면 EUC-KR로 저장되는 것 같습니다.)

그리고 확인을 눌러 저장!

그러고 난 후에 다시 빌드해보면 어떤 문제도 발생하지 않고 정상적으로 글자가 표시됩니다.

그리구! 일본어도 가능!

뭐 어쨌든 이런 것이고.. 분명히 항상 이 설정을 하는 것은 불편하죠..

그러니 바꿔보죠!

(Visual Studio Code는 인코딩 자동 설정으로 바로 되던데..)

Visual Studio 기본 인코더 설정

이 방법은 프로젝트마다 설정해야되니.. 불편하긴 하지만.. 어쨌든 되니 뭐 암튼

일단 프로젝트 파일로 들어갑니다.

프로젝트 파일은 솔루션 폴더 안에 있습니다.

즉! 보통 프로젝트를 만들면 솔루션 이름을 지정하고 프로젝트 이름을 지정하게 되는데

source > repos > 솔루션 이름 > 프로젝트 이름 이런식으로 저장되는데 여기에서 우리가 해야할 작업은 프로젝트 이름 쪽 폴더 입니다.

 

프로젝트 폴더엔 vcxproj 파일이나 cpph 파일을 작성했던 모든 코드들을 볼 수 있는 폴더인거죠

뭐 암튼 여기에서 

이런 파일을 ".editorconfig"생성합니다. 전 그냥 바로 메모장 파일 생성하고 이름하고 확장자 전체 다 바꿨습니다.

그리고 그 안에 이렇게 작성합니다.

root = true

[*]
charset = utf-8

그리고 저장하면 끄읕!

 

그리고 이제 Visual Studio에서 파일을 생성해보면?!!

기존에 있던 파일 인코더
.editorconfig 설정을 한 후 생성한 파일 인코더

이런식으로 바뀌었습니다!

어렵네요..

요약

파일 > 다른 이름으로 이름.cpp 저장(A)... > 저장 오른쪽 삼각형 클릭 > 인코딩하여 저장(V)... > 인코딩(E): 아래 메뉴에서 유니코드(서명 없는 UTF-8) - 코드 페이지 65001 이걸로 변경

 

항상 UTF-8로 자동저장 방법

프로젝트 폴더로 진입 > .editorconfig 파일 생성 > 아래 코드 입력 후 저장

root = true

[*]
charset = utf-8

 

 

.editorconfig 설정 관련 사이트

https://editorconfig.org/

 

EditorConfig

What is EditorConfig? EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection o

editorconfig.org

근데 왜이리 중간 중간 말투가 바뀌는거지..

반응형
반응형

빠르게 말하면 Marlin 2.0 이상에는 이스터에그인 게임이 숨겨져 있다.

설정을 하려면 Marlin 2.0 소스코드를 열어서 Configuration_adv.h 파일을 연다.

그리고 Ctrl + F로 Game이라고 검색하면

이런식으로 나오는데

이런식으로 주석을 제거해주면 활성화는 끝난다.

그렇게 되면 저 3개의 게임을 할 수 있게 되는데 그냥 제목대로 그 게임이다..

 

근데 맨 마지막 GAMES_EASTER_EGG는 하면 안될 것 같다..

진짜 이스터에그 처럼 할려고 메뉴창에 들어가보니 위에 빈칸이 있고 그 밑에 Game 메뉴가 있었다.. 해볼 분은 해보시고..

 

뭐 어쨌든 활성화 시키고 펌웨어를 업데이트 해보니 About Printer > Games 메뉴에 3가지 게임이 추가되었다.

이런식으로

들어가면 된다.

 

그리고 해보니 겁나 잘 됨!

근데 조종은 동그라미 휠 그걸로 하게 되는데 큰거일 수록 좋은 것 같다 움직이는게 빡세다..

 

이렇게 3가지 게임이 있고 아래는 플레이 해본거

반응형
반응형

잘은 모르겠지만 아마 프로젝트에서 라이브러리 끼리 런타임이 달라서 그러는 것 같다.

불일치가 검색되었습니다. 뒤에 Mt 뭐시기 값이 Mtd 뭐 이런식으로 안맞다는데

그냥 맞추면 끝나는 문제!

 

프로젝트 오른쪽 클릭 > 속성 > ("프로젝트 이름" 속성 페이지) 에서 구성 속성 > C/C++ > 코드 생성 > 런타임 라이브러리

이걸 맞춰주면 된다. 

내가 맞춘 방법으로는 

오류에서 MT_StaticRelease 값이 MD_DynamicRelease 뭐 이런식으로 떴었는데 MD_DynamicRelease 쪽꺼가 내 프로젝트꺼고 MT_StaticRelease가 라이브러리 쪽 같아서 그냥 내 프로젝트를 MT_StaticRelease쪽에 맞췄다. 그냥 런타임 라이브러리 설정에서 MDMT로 바꾼거

이런식으로

 

요약하면 

'RuntimeLibrary'에 대해 불일치가 검색되었습니다. 'MT_StaticRelease' 값이 'MD_DynamicRelease'(프로젝트 이름.obj에 위치) 값과 일치하지 않습니다.

이럴 때 프로젝트의 속성 페이지에서 구성 속성 > C/C++ > 코드 생성 > 런타임 라이브러리MT로 바꿔주면 끝!

 

그리고 더 찾아본 것인데.

MT정적 라이브러리로 연결해서 dll 파일로 동적으로 연결하지 않고 exe에 다 넣어서 정적으로 실행되게 하고

MD동적 라이브러리로 연결해서 dll 파일이 필요한 건데..

https://cheongpark.tistory.com/16

 

DLIB & OPENCV 진짜 쉽게 깔아보기 C++

학교에서 프로젝트를 받아버려서.. 해야하는 상황.. 내 프로젝트를 위해선 DLIB와 OPENCV가 필요한데.. 정말 2~3일동안 수없이 도전해보다가 굉장히 간단한 방법을 찾아서 알려줄까함! (왜이리 dlib는

cheongpark.tistory.com

여기에서 DlibVCPKG로 깔았었는데 난 이때

이 항목이 있어서 그냥 깔아봤다. 근데 여기에 필요한 거였다..

VCPKG로 깔은 것도 정적 라이브러리로 가능한가보다..

 

그래서 속성 페이지로 들어가보니 VCPKG라는 항목이 있는데 거기에 자세히 보니 Use Static Libraries 이런게 있었다.

그래서 정적 라이브러리로 만드는건가 해서 예로 바꿨더니..!

빌드 해서 보니 원래는 사진에 관한 dll 파일들도 막 생기고 그랬는데..

이젠 안생긴다!

다만 윈도우 버전에 따라 필요로 하는 dll 파일들은 생기지만..

 

뭐 어쨌든 더 좋아진 것 같다!

 

암튼 끝

반응형
반응형

QT를 빌드하고 실행해보면 이상하게 제목처럼 Qt6Core.dll Qt6Gui.dll Qt6Widgets.dll 이 세개의 파일이 없다면서 실행을 거부해버린다.

뭐 저걸 찾아서 넣으면 된다만.. 도데체 어딨지 했다는..

 

그래서 찾아보니 다른 사용자들도 사용할 수 있게 배포를 하기 위한 명령어가 있었다는걸..

windeployqt

이거

 

자신이 QT 프로젝트를 만들 때 사용했던거.. Visual Studio로 했으면 MSVC 2019 이런거..

어쨌든 설치했다면 Qt 버전 (설치 된거) 뭐 이런식으로 뜰꺼다..

내껀 이렇게 

그래서 이걸 실행해서 여기에다가 windeployqt "exe 파일 경로" / 예) windeployqt "C:\Users\Deploy\QtProject.exe" 이런식으로 입력하면

엄청난 여러가지 문구가 뜨면서

대충 이거하고 여러가지 dll 파일들을 생성하면서 다른 컴퓨터에서도 구동할 수 있게 파일을 만들어준다..

 

근데 문제는 엄청 귀찮다.. 그리고 명령어가 생각 안날 때도 있다.

 

그래서 Visual Studio 경우 설정을 찾아보니

Qt Project Setting > Run Deployment Tool 이 있었다.

이걸 이용하면 될 것 같아.

어차피 테스트는 디버그에서 할꺼라 Release에서 하는 경우는 배포용으로 빌드 할 때 밖에 없기 때문에

 

구성을 Release로 하고

이런식으로 예로 바꾸니

 

바로 빌드 하자마자 windeployqt 이 명령어 없이 바로 배포 파일들을 생성해주었다..!

근데.. 자주 테스트로 컴파일 해보는 거에다가 저걸 하는건 않좋을 것 같다.. 너무 느려..

 

뭐 어쨌든 요약!

3가지 파일이 없는 이유는 배포 툴로 파일들을 생성 안한 것이며 생성을 간편하게 할려면 Visual Studio의 경우 속성 페이지로 가서 구성 속성 > Qt Project Setting > Run Deployment Tool로 바꿔주면 Release로 빌드 할 때마다 배포 파일로 자동으로 만들어줌!

아니면 windeployqt "exe 파일 경로" 이 명령어로 해도 상관없음!

반응형
반응형

Configuration.h에서 NOZZLE_TO_PROBE_OFFSET의 일부만 검색해도 나온다.

 *     +-- BACK ---+
 *     |    [+]    |
 *   L |        1  | R <-- Example "1" (right+,  back+)
 *   E |  2        | I <-- Example "2" ( left-,  back+)
 *   F |[-]  N  [+]| G <-- Nozzle
 *   T |       3   | H <-- Example "3" (right+, front-)
 *     | 4         | T <-- Example "4" ( left-, front-)
 *     |    [-]    |
 *     O-- FRONT --+
 */
#define NOZZLE_TO_PROBE_OFFSET { -41, -9, -0.92 }

으음.. 3D 프린터에서 오토레벨링 센서가 있거나.. 없거나.. 이 설정은 중요한 것 같다.

기본적으로 설정은 되어 있지만.. 프린터마다 다 위치가 다르니 개개인 프린터를 다 설정해주는게 좋을 것 같다 생각되지만.. 역시 귀찮긴 함..

 

보통 같은 방법이라면 3D 프린터로 값을 찾고 M851 인가..? 그걸 써서 GCode를 보내서 저장하고 그러는데.. 내껀 이상하게 EEPROM에 저장하면 프린터가 터지는지 리붓이 된다.. 그래서 음.. 펌웨어에 직접 박아버려야 한다..

 

일단 위에 코드의 설정값은 내가 직접 한 것이고.. CR10S 기준으로 BLTOUCH는 저 값을 사용하면 될 듯 하다.. 마지막 Z 값은 각자 달라야 겠지만

 

어쨌든 저건 노즐이 어디에 위치 해 있는지 알려주는 코드다!

오토레벨링 센서를 달았다면 더더욱 중요한데 자기의 레벨 센서를 베드의 어느 지점을 정확하게 찍을지 선정하는 것이기도 하다..!

 

그냥 BLTouch하고의 Nozzle의 거리다 직접 자로 측정해도 되고 수동으로 맞춰가면서 맞춰도 되고.. 아무거나 상관없다..!

어쨌든 저걸 잘 설정해야 오토레벨링 할 때 각 점을 잘 찍게 된다.

저거 설정 안하고 하면 

각 점을 찍을 때 오토레벨링 센서는 그것보다 왼쪽으로 아마 찍을꺼다. 그냥 노즐 기준으로 찍는 거겠지만.. 뭐

정리 : 저 값을 변경해야 레벨링할 때 각 점으로 정확하게 이동시킬 수 있다.

반응형
반응형

아마 글꼴을 찾는데 문제가 있을 수 있습니다 "맑은 고딕"은 정상적으로 작동되지만 컴퓨터마다 다를 수 있을 것 같습니다. 될 수도 있고 안 될 수도 있다는 점.. 안된다면.. 폰트 쪽 코드를 수정하면 될지도..?

 

일단 음.. 이걸 성공하게 된건.. 한국어나 영어로 찾아볼 땐 아무리 찾아도 안나왔는데.. 일본에는 전문가들이 많으니깐 있지 않을까해서 일본어로 검색해보니.. 역시 있었다. 그래서 해결하게 됨

 

바로 가져갈 분은 맨 아래쪽에 있어요.

 

https://jitaku.work/it/category/image-processing/opencv/write_japanese/

 

C++のOpenCVで日本語をputTextする

Top 作成日: 2020.06.29 C++のOpenCVで日本語をputTextする Pythonの場合比較的容易にできる、日本語を画面描画する方法。 C++はそういったことができないので非常に困っていた。 で、ネットからパク

jitaku.work

일단 나는 여기 것을 사용했는데. 여기에 있는 코드를 바로 쓰면 당연히 안될꺼다.

HFONT hFont = ::CreateFontA(
        fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
        SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
        VARIABLE_PITCH | FF_ROMAN, fontname);

코드를 보면 이런데.. 저기 아래 SHIFTJIS_CHARSET 저것때문에 안된다. 아마 인코딩 문제 같은데 뭐 저거를 다른 대부분 언어도 되게 할려면 DEFAULT_CHARSET으로 하면 아마 될 것 같다. 당연 한국어도 됨!

 

일단 저걸로 하면 되고

추가적으로 수정한 것

일단 내 프로젝트에선 좀 중요하기 때문에 얘를 그냥 출력하면 안티에일리어싱이 결국엔 안된다.

위의 코드에서 안티에일리어싱을 키면 되는데 킨다 하더라도 코드 때문에 결국은 안된다.

 

일단 이 코드의 방식을 보면 먼저 MFC로 어디선가?에서 적을 OpenCV Mat에서의 가로 길이만큼의 텍스트 이미지를 생성한 후 가져와서 비트맵을 Mat 방식대로 바꿔서 적용하는 방식이다. (아마 맞을꺼임)

 

근데 저기 코드를 대충 보면

if (_tmp[0] == 0 && _tmp[1] == 0 && _tmp[2] == 0) {
                    _img[0] = (unsigned char)color.val[0];
                    _img[1] = (unsigned char)color.val[1];
                    _img[2] = (unsigned char)color.val[2];
                }

이런 코드가 있다. 그리고 위쪽에 보면 back_color로 0x99가 정의 되어 있는데.. 이걸 보면 대충 알 수 있다. 일단 MFC에서 텍스트 이미지를 생성하면 텍스트 밖은 기본적으로 흰색(255, 255, 255), 텍스트는 검은색(0, 0, 0)이다.이다. 또한 0x99는 153으로 RGB 153 153 153 뭐 이래보면 회색이다. 최대가 255이니.. 그래서 최종적으로 저 코드는 텍스트외의 배경 (153, 153, 153)과 (255, 255, 255) 부분을 제외한 검은색 부분(텍스트 부분)을 가져와 사전에 정의한 RGB색대로 다시 설정하는 방식이다.

 

이 때문에 이 코드에선 아무리 안티에일리어싱을 한들.. 안티 에일리어싱이 픽셀 사이사이에 텍스트보다 연한 색을 찍는건데 이 것들이 다 제외되면서 결국엔 안티 에일리어싱이 안찍힌다..

 

그래서 내가 생각한 방식은 안티 에일리어싱의 경우 연한 색도 처리해야하기 때문에 배경색이 바뀔때마다 당연히 글자 색도 변경될테니 배경색을 직접 지정하고 텍스트 색도 직접 지정해서 나중에 배경색만 빼는 것이다. 그러면 결국엔 적용되는건 텍스트의 진한 픽셀부터 연한 픽셀까지이다. 그래서 이 방법으로 코딩한건 뭐 아래에 넣을꺼고

 

또한 내가 지정한 것 중에 다른 것들도 있지만 ori가 있다. 내가 당시 했을때 오리엔테이션인가 뭔가 하는걸로 줄여서 적은 것 같은데.. 잘 못 지정한 것 같다.

어쨌든 저 코드를 보면

int posX = (ori == 0 ? org.x : (ori == 1 ? org.x - (size.cx / 2) : org.x - size.cx)); //기준이 왼쪽이면 그대로, 중간이면 기준점 - 넓이 / 2, 오른쪽이면 기준점 - 넓이

대충 이렇게 적어놨다. 조건연산자로 이리저리 해놨는데 주석문을 보면 대충 알 수 있다. 0이면 왼쪽 기준 1이면 중간 기준 2이면 오른쪽 기준

말 그대로다. 사전에 정의한 글자 위치대로 0이면 텍스트의 맨 왼쪽 기준으로 텍스트가 생성되고 1이면 텍스트의 중간으로 생성 2이면 텍스트의 오른쪽 끝으로 생성된다.

 

그리고 세로 축도 할려했는데.. 음..! 이 때 당시엔 필요가 없었어서.. 하실 분들은 직접 하시길! 내가 기억하기론 세로는 맨 위쪽 기준으로 되는걸로 알고 있다.

 

코드를 보면 뭐 배경색 칠하는 것도 있고 텍스트 색 지정하는 것도 있고 그렇다.. 어쨌든 그런거임!

 

이제 코드를 보여줌!

코드

void _putText(cv::Mat& img, const cv::String& text, const cv::Point& org, const int ori, const char* fontname, const int fontWeight, const double fontScale, const bool anti, const RGBScale textcolor, const RGBScale bkcolor) {
	int fontSize = (int)(10 * fontScale);
	int width = img.cols;
	int height = fontSize * 3 / 2;

	HDC hdc = CreateCompatibleDC(NULL);

	HBRUSH hBrush = CreateSolidBrush(bkcolor.rgb);

	RECT rect;
	rect.left = rect.top = 0;
	rect.right = width;
	rect.bottom = height;

	BITMAPINFOHEADER header;
	ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
	header.biSize = sizeof(BITMAPINFOHEADER);
	header.biWidth = width;
	header.biHeight = height;
	header.biPlanes = 1;
	header.biBitCount = 24;
	BITMAPINFO bitmapInfo;
	bitmapInfo.bmiHeader = header;
	HBITMAP hbmp = CreateDIBSection(NULL, (LPBITMAPINFO)&bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0);
	SelectObject(hdc, hbmp);

	FillRect(hdc, &rect, hBrush);

	BITMAP  bitmap;
	GetObject(hbmp, sizeof(BITMAP), &bitmap);

	HFONT hFont = CreateFontA(
		fontSize,
		0,
		0,
		0,
		fontWeight,
		FALSE,
		FALSE,
		FALSE,
		DEFAULT_CHARSET,
		OUT_DEFAULT_PRECIS, //SHIFTJIS_CHARSET -> DEFAULT_CHARSET으로 변경
		CLIP_DEFAULT_PRECIS,
		(anti ? ANTIALIASED_QUALITY : DEFAULT_QUALITY), //안티를 허용하면 해주고 아니면 안해주고
		VARIABLE_PITCH | FF_ROMAN,
		fontname);
	SelectObject(hdc, hFont);
	SetTextColor(hdc, textcolor.rgb);
	SetBkColor(hdc, bkcolor.rgb);

	//넓이 높이 구하기
	SIZE size;
	GetTextExtentPoint32A(hdc, text.c_str(), (int)text.length(), &size);

	TextOutA(hdc, 0, height / 3 * 1, text.c_str(), (int)text.length());
	int posX = (ori == 0 ? org.x : (ori == 1 ? org.x - (size.cx / 2) : org.x - size.cx)); //기준이 왼쪽이면 그대로, 중간이면 기준점 - 넓이 / 2, 오른쪽이면 기준점 - 넓이
	int posY = org.y - (size.cy / 2 + 5);

	unsigned char* _tmp;
	unsigned char* _img;
	for (int y = 0; y < bitmap.bmHeight; y++) {
		if (posY + y >= 0 && posY + y < img.rows) {
			_img = img.data + (int)(3 * posX + (posY + y) * (((bitmap.bmBitsPixel / 8) * img.cols) & ~3));
			_tmp = (unsigned char*)(bitmap.bmBits) + (int)((bitmap.bmHeight - y - 1) * (((bitmap.bmBitsPixel / 8) * bitmap.bmWidth) & ~3));
			for (int x = 0; x < bitmap.bmWidth; x++) {
				if (x + posX >= img.cols) {
					break;
				}

				if (_tmp[0] != bkcolor.b || _tmp[1] != bkcolor.g || _tmp[2] != bkcolor.r) { //순서를 bgr를 써서 bgr로 한거, rgb 순서이면 그걸로 해야함
					_img[0] = (unsigned char)_tmp[0];
					_img[1] = (unsigned char)_tmp[1];
					_img[2] = (unsigned char)_tmp[2];
				}
				_img += 3;
				_tmp += 3;
			}
		}
	}

	DeleteObject(hFont);
	DeleteObject(hbmp);
	DeleteDC(hdc);
}

주석문 보고 뭐 대충 하면 될 것 같다. 난 OPENCV의 기본 MAT의 설정인 BGR때문에 아래가 BGR 기준이고 RGB면 순서를 바꿔서 작성해야 할 것이다.

 

cv::Mat& img, const cv::String& text, const cv::Point& org, const int ori, const char* fontname, const int fontWeight, const double fontScale, const bool anti, const RGBScale textcolor, const RGBScale bkcolor

파라미터를 대충 설명하면

  • cv::Mat& img -> 텍스트를 적용할 이미지
  • cv::String& text -> 출력할 텍스트
  • cv::Point& org -> OpenCV 이미지에서 텍스트를 지정할 위치
  • int ori -> 텍스트 위치를 지정할 때 왼쪽 중앙 오른쪽으로 어느 위치로 정렬해서 출력할지
  • char* fontname -> 폰트 이름 (예: 맑은 코딕)
  • int fontWeight -> 글자의 굵기 (예: FW_BOLD 이런거 하면 됨.. 그냥 숫자로 해도 되고)
  • double fontScale -> 글자 크기 (예: 이건 좀 보정을 안했는데 그냥 무조건 큰 숫자 적으면 진짜 커지므로 기본 생각했던 것보다 반 작게 줄여서 적으면 아마 맞을꺼다)
  • bool anti -> 안티에일리어싱을 할꺼냐 말꺼냐
  • RGBScale textcolor -> 텍스트의 컬러 지정 (예: RGBScale(255, 0, 0))
  • RGBScale bkcolor -> 배경색 지정 (예: RGBScale(255, 255, 255))

어쨌든 이정도다.. 뭐 쓰다보니 파라미터가 너무 많아지긴 했지만.. 뭐 내가 쓰는건데 뭐 어때!

_putText(outImg, "나", cvPoint(50, 50), 1, "맑은 고딕", FW_BOLD, 6, true, RGBScale(0, 0, 0), RGBScale(255, 255, 255));

사용 예시는 위와 같다.

 

어쨌든 그렇다. 이거 글 쓰는 것도 힘들 구 생각하는 것도 힘들었는데..

나중에 자기 글에다 쓰고 싶다면... 적어도 링크라도.. 부탁.. (이거 그럼 만든게 2022년 11월 쯤에 만들었으니.. 고등학교 2학년 때 만든거군.. 아 여기 학교 C/C++과목 전혀 없음)

 

뭐 어쨌든 끄읕!

 

얼마나 사용해줄진 모르겠지만.. C++은 겁나 복잡해!!

 

(파이썬은 짧고 쉽던데.. 방식은 이거와 비슷)

 

2023-03-01 추가

코드에서 RGBScale에 대한 구조체 내용이 없어서 다시 정리하고 구조체에 대한 것도 새로 적습니다.

struct RGBScale {
    int r = 0;
    int g = 0;
    int b = 0;
    int rgb = 0;

    RGBScale(int r, int g, int b) {
        this->r = r;
        this->g = g;
        this->b = b;

        this->rgb = RGB(r, g, b);
    }
};

RGBScale(0xFF, 0xFF, 0xFF)로 적으면 되는데 0xFF는 그냥 16진수 이기 때문에 0부터 255 숫자중 원하는 색깔에 맞춰 적으시면 됩니다! 그리고.. 기본적으로 cv::Mat 생성할 때 RGB가 아닌 BGR로 생성하기 때문에 아마 RGB 이미지를 넣어서 적용시키면 색깔이 다르게 나올꺼기 때문에.. 인풋엔 BGR로 넣으시면 됩니다. 수정할려면 아래 적혀있는 코드에서 비트맵을 OpenCV로 바꿔주는 곳에서 b, g, r 적혀있는 것을 r, g, b로 변경하시면 될겁니다. RGBScale를 따로 만든 이유는 그냥 r, g, b도 추출하고 rgb도 출력하고 하기 위함!

 

아래는 다시 정리해본 코드!

void CPputText(cv::Mat& O_image, cv::String text, cv::Point org, int ori, const char* fontName, int fontWeight, double fontScale, RGBScale textColor, RGBScale bkColor) {
	int fontSize = (int)(10 * fontScale);
	int width = O_image.cols;
	int height = fontSize * 3 / 2;

	HDC hdc = CreateCompatibleDC(NULL); //텍스트 이미지를 만들어두는 곳 같은거

	HBRUSH hBrush = CreateSolidBrush(bkColor.rgb); //채우는 방식인데 bkColor로 단색으로 채우는거

	//텍스트 이미지 크기 정하는거
	RECT rect;
	rect.left = rect.top = 0;
	rect.right = width;
	rect.bottom = height;

	//비트맵의 구조를 사전에 정의하는 것 크기나 색
	BITMAPINFOHEADER header;
	ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
	header.biSize = sizeof(BITMAPINFOHEADER);
	header.biWidth = width;
	header.biHeight = height;
	header.biPlanes = 1;
	header.biBitCount = 24;
	BITMAPINFO bitmapInfo;
	bitmapInfo.bmiHeader = header;
	HBITMAP hbmp = CreateDIBSection(NULL, (LPBITMAPINFO)&bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0);
	SelectObject(hdc, hbmp); //hdc에 적용? 하는 거

	FillRect(hdc, &rect, hBrush); //지정한 크기만큼 완전하게 채우는거 (다 채움)

	BITMAP bitmap;
	GetObject(hbmp, sizeof(BITMAP), &bitmap);

	//텍스트 이미지 만들 때 사용할 수 있는 폰트를 생성? 하는 그런거
	HFONT hFont = CreateFontA(
		fontSize,
		0,
		0,
		0,
		fontWeight,
		FALSE,
		FALSE,
		FALSE,
		DEFAULT_CHARSET, //한국어나 일본어나 해주게 하는거 (아마)
		OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		ANTIALIASED_QUALITY, //안티 에일리어싱을 켜주는거
		VARIABLE_PITCH | FF_ROMAN,
		fontName);
	SelectObject(hdc, hFont);
	SetTextColor(hdc, textColor.rgb);
	SetBkColor(hdc, bkColor.rgb);

	//계산을 위해 미리 텍스트의 사이즈 구하는거
	SIZE size;
	GetTextExtentPoint32A(hdc, text.c_str(), (int)text.length(), &size);

	TextOutA(hdc, 0, height / 3 * 1, text.c_str(), (int)text.length()); //이미지에 텍스트 적는거
	int posX = (ori == 0 ? org.x : (ori == 1 ? org.x - (size.cx / 2) : org.x - size.cx)); //기준 정하는거 0은 텍스트의 왼쪽 1은 텍스트의 중간 2는 텍스트의 오른쪽
	int posY = org.y - (size.cy / 2 + 5);

	//비트맵 사진을 OpenCV이미지에 삽입해주는거
	unsigned char* _tmp;
	unsigned char* _img;
	for (int y = 0; y < bitmap.bmHeight; y++) {
		if (posY + y >= 0 && posY + y < O_image.rows) {
			_img = O_image.data + (int)(3 * posX + (posY + y) * (((bitmap.bmBitsPixel / 8) * O_image.cols) & ~3));
			_tmp = (unsigned char*)(bitmap.bmBits) + (int)((bitmap.bmHeight - y - 1) * (((bitmap.bmBitsPixel / 8) * bitmap.bmWidth) & ~3));
			for (int x = 0; x < bitmap.bmWidth; x++) {
				if (x + posX >= O_image.cols)
					break;

				if (_tmp[0] != bkcolor.b || _tmp[1] != bkcolor.g || _tmp[2] != bkcolor.r) { //텍스트 이미지의 배경 컬러는 없애기 위한 것, bgr 순서로 하는 이유는 Mat 이미지를 처음에 만들 때 BGR 순이여서
					_img[0] = (unsigned char)_tmp[0]; //B
					_img[1] = (unsigned char)_tmp[1]; //G
					_img[2] = (unsigned char)_tmp[2]; //R
				}
				_img += 3;
				_tmp += 3;
			}
		}
	}

	//메모리에서 삭제해주는거 이거 안하면 메모리 계속 사용함
	DeleteObject(hBrush);
	DeleteObject(hFont);
	DeleteObject(hbmp);
	DeleteObject(hdc);
}
cv::Mat inputMat(500, 500, CV_8UC3);
CPputText(inputMat, "안녕!", cvPoint(inputMat.cols / 2, inputMat.rows), 1, "맑은 고딕", FW_BOLD, 6, RGBScale(0xFF, 0xFF, 0xFF), RGBScale(0, 0, 0));

아아마 이렇게 하면 500 * 500 으로 이미지를 생성하고 그 중간에 텍스트를 넣는거니 완전 중간은 아니고.. 세로가 좀 아래로 쳐져있긴 하지만.. 저렇게 하면 잘 작동은 합니다!

반응형
반응형
/**
 * Default Max Feed Rate (linear=mm/s, rotational=°/s)
 * Override with M203
 *                                      X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
 */
#define DEFAULT_MAX_FEEDRATE          { 3000, 3000, 100, 80 }

Configuration.h에서 저 부분을 찾으면 나온다.

주석으로 설명되어 있는 부분을 보면.. x, y, z [, I [, J... 등등

뭐 이래 되어있는데.. 대괄호 신경쓰지 않고 보면

X, Y, Z, E0 이렇게 보면 될 것 같다.

X는 가로축 속도

Y는 세로축 속도

Z는 높이축 속도

E0은 익스트루더 0 속도

 

원래는 2500, 2500, 100, 50 이래 되어있을텐데

내껀 좀 더 빨리 출력하는걸로 바꿔볼까 해서 3000으로 바꾸고 50 -> 80으로 바꿔봤다.

 

참고로 큐라에서 리트렉션 속도를 빠르게 한다해도 여기에서 익스트루더 속도가 리트렉션 속도보다 낮으면

결과적으로 리트렉션 속도는 익스트루더 최대 속도 밖에 안된다..

 

그렇기 때문에 리트렉션 속도를 50 이상으로 맞출꺼라면 저것의 E0 속도를 50 이상으로 맞출 것을.. 권장..

 

과연 내 프린터는 얼마나 빨리 출력이 가능할까?

반응형
반응형
#define HEATER_0_MAXTEMP 300
#define HEATER_1_MAXTEMP 300
#define HEATER_2_MAXTEMP 300
#define HEATER_3_MAXTEMP 300
#define HEATER_4_MAXTEMP 300
#define HEATER_5_MAXTEMP 300
#define HEATER_6_MAXTEMP 300
#define HEATER_7_MAXTEMP 300
#define BED_MAXTEMP      120
#define CHAMBER_MAXTEMP  60

Configuration.h에서 저런거 검색해보면 있을꺼다.

저기에서 보통은 275 이럴텐데 (아닐 수도.. 난 내 프린터 기본 펌웨어를 가져온거라)

HEATER_0_MAXTEMP를 자신이 원하는 최대 온도로 변화시키면 될 것 같다.

BED_MAXTEMP는 최대 베드 온도 설정하는거

 

그리고 저거 8개 있는 이유는.. 여러개 핫엔드 사용하면 그러는 것 같다.

난 한개만 사용하지만 그냥 다 설정함!

 

(내껀 500도 까지도 버틴다던데.. 프린터가 녹는거 아닌가..)

 

#define HEATER_0_MINTEMP   0
#define HEATER_1_MINTEMP   0
#define HEATER_2_MINTEMP   0
#define HEATER_3_MINTEMP   0
#define HEATER_4_MINTEMP   0
#define HEATER_5_MINTEMP   0
#define HEATER_6_MINTEMP   0
#define HEATER_7_MINTEMP   0
#define BED_MINTEMP        0
#define CHAMBER_MINTEMP    0

참고로 바로 위에 이것도 있는데 이건 아마 5로 설정되어있을꺼다.

나는 0으로 설정한 이유는 요즘 겨울이기도 하고.. 가끔 내 프린터가 말썽이기 때문이다.

써미스터가 5도 아래로 내려가면.. 삐삐 거려서 0으로 설정한 것..

 

온도 측정할 때 최소 최대값을 벗어나면 아마 프린터는 자동으로 정지할꺼다.. 

짜증

반응형

+ Recent posts