압축파일 참조 Qt Mingw32bit 라이브러리 사용

QRCode.z01
10.00MB
QRCode.z02
10.00MB
QRCode.zip
2.05MB

구조체는 클래스내부에서만 사용하는 경우가 아니면 GlobalStruct클래스를 따로 만들어서 빼는게 훨씬 나은것같다.

 

가령

 

class a
{
private:
 	struct DO_SOMTHING
 	{
 	};
};

 

이런식으로 클래스 내부에서 한정적으로 쓰는거라면 내부 구조체로 사용하면 되지만

만약 다른곳에서 해당 구조체를 참조해야하는 상황이 벌어지면 

 

 

class globalData
{
public:

    struct DO_SOMETHING
    {
    };
};







//a class.h


#include "globalData.h"


class a
{

private:
	globalData::DO_SOMTHING d;
};


or



globalData::DO_SOMTHING d;

 

 

요런식으로 아예 그냥 공용 구조체 클래스를따로 빼버리는게 낫다.

(구조체 선언만 전문적으로 관리하는 클래스 - cpp가 없이 구조체 인터페이스 느낌이라고 생각하면 편하다.)

네임스페이스를 쓸까도 생각해봤는데 저게 더 깔끔하고 네임스페이스는 뭔가 패키지 전체를 구분짓는 듯한 뉘앙스라

저렇게 별도 클래스로 관리중.

지금 별생각없이 클래스별로 구조체만들어놨다가.. 다뜯어고치고있다 ㅡ,.ㅡ 

 

요새 아키텍트에 꽂혀서 >_< 책을 미친듯이 찾아다니고있다.

그냥 회사 일하다가 코딩하다 피곤할때 틈틈히보고 쉬는시간에 보고 점심시간에보고 있는 수준이라

빨리 나가지는 않지만 이제 6년차를 바라보는 개발자로서 공감가는 부분이 되게 많아서

목록을 공유한다.

 

 

1. 클린코드 시리즈 - 로버트C. 마틴

2. 리팩토링 - 마틴 파울러

3. 구현 패턴 - 켄트 벡

4. 소프트웨어 장인 - 산드로 만쿠소

 

 

그외 내가 주력으로 삼는 언어는 C++이기에 덤으로..

Effective C++, Effective Modern C++(스콧 마이어스)

 

Effective시리즈는 다른언어 버전으로 많이 있으니 한번 찾아서 읽어보면 도움이 될것이다.

Effective시리즈는 언어에 대한 기본기를 갖춰주는 책들이라면

 

위쪽의 책들은 아키텍트와 마음가짐에 관한 책이다.

 

내가 비트에서 고급과정 수료하고 비트컴퓨터 회장님이 축하인사말을 할때 이런말을 들었다.

"지식은 나누면 커진다."

 

그래서 나누는것이다 ^^

 

축하 인삿말로 하시진 않았지만 이런 말씀도 자주하신댄다.

 

"십자가를 보면 중심에서 위보다 아래가 더 긴데 이것은 윗사람보다 아랫사람을 향해 더 많은 인맥을 쌓아야 한다는 것을 뜻하고, 왼쪽과 오른쪽이 같은 것은 균형감각을 유지하기 위해서는 자신과 뜻이 맞는 사람뿐만 아니라 뜻이 맞지 않는 사람도 똑같이 사귀어야 한다는 의미”

 

비록 비트교육센터에서의 1년은 무자비하고 스파르타식의 혹독한 시간(아침 9시 강의 시작 오후 6시 종료 밤12시까지 자습 - 밥먹는 시간빼고 해당 층 밖에 못나감 -ㅅ- (의무교육), 새벽에 집에서 공부(자율))이었지만 그분이 있었기에 내가 지금 이자리에 있나 싶다. 정말 고마운분이었다.

 

ps. 축사때 재미가없다는 것은 못한다는 뜻이라고 팩폭도 시전했다. 꼬우면 잘하라고하셨지... ㅋ 

그냥 개발하면서 든 생각이다. 솔직하게 말하자면 Copy&Paste만 할줄알아도 된다 이런이야기는 아니다.

개발을 하다보면 정말 세상엔 천재가 많고 똑똑한 사람이 많다.

그런데 모두가 박사일필요도 모두가 천재일 필요도 없다.

나같은 평범한 사람은 천재들과 박사들의 개발사상 이념 기본구조를 정확하게 이해하고 응용만 할줄알아도

어설프게 알고리즘 직접짜서 어설프게 자기가 구현했다고 자기만족하는 사람들보다 훨씬 좋은코드를 짤수있다고 

감히 단언한다.

 

우리가 쓰고있는 프레임워크 혹은 라이브러리들은 짧은 프로그래밍 역사(이제 70년 넘음)에서 수십년에 걸쳐 

전세계의 수많은 사람들에게 온갖 피드백과 우리보다 똑똑한(?) 천재들에 의해 무수한 개량과 검증을 받았음을 잊지마라.

 

물론 자기자신이 정말뛰어난 사람이라면 직접만들어도 상관없지만 시간과 노력을 생각해봐라.. 인생은 짧다 배울것은 끝도없이 생겨나고 매일매일 따라 잡지 못하면 도태된다. 아무도 만든사람이 없어서 자신이 직접만들고 공유해서 그게 라이브러리가 된다면 그거야 말로 박수 받을 일이지만 그만한 시간적 금전적 여력이있는사람이 몇이나 될까.

 

가끔 직접 모든걸 구현해야 하는 강박관념 걸린사람을 본다. 과거의 나도 그랬다. 그런데 개발하고 경력쌓일수록 별의별 생각이 다든다. 과연 이게 최선인가. 내가 선택한 대답은 어설프게 뱁새가 황새쫒아가는것보다 황새가 어떻게 그렇게 잘걸을수있는지 무슨생각으로 그렇게 걸었는지 이해하고 최대한 내실정에 맞게 개조하는것으로 결론을 내렸다.

그것만해도 당신은 충분히 훌륭한 개발자라고 생각한다.

'잡담' 카테고리의 다른 글

소프트웨어 개발자 추천 책 목록  (3) 2020.02.28
우리가 클린코드 시리즈를 읽어야 하는 이유  (1) 2020.02.24
그냥 요즘 드는 생각  (1) 2020.02.19
라즈베리 파이 장비개발중  (1) 2018.06.22
이직..-ㅁ-  (1) 2017.11.20

 


설명이 더필요한가?(Any Question?) 
선택은 여러분의 판단에 맡기겠다.

'잡담' 카테고리의 다른 글

소프트웨어 개발자 추천 책 목록  (3) 2020.02.28
모두가 천재이자 우수 할 필요는없다.  (3) 2020.02.28
그냥 요즘 드는 생각  (1) 2020.02.19
라즈베리 파이 장비개발중  (1) 2018.06.22
이직..-ㅁ-  (1) 2017.11.20

//출처 : 내가만든거

QString CUtil::hexaToHexaString(uint target, ENDIAN endian)
{
    QString retValue;
    uchar targetBuf[4] = { 0, };
    uchar* targetPtr = (uchar*)&target;

    if (endian == ENDIAN_BIG)
    {
        targetBuf[0] = targetPtr[3];
        targetBuf[1] = targetPtr[2];
        targetBuf[2] = targetPtr[1];
        targetBuf[3] = targetPtr[0];
    }
    else
    {
        targetBuf[0] = targetPtr[0];
        targetBuf[1] = targetPtr[1];
        targetBuf[2] = targetPtr[2];
        targetBuf[3] = targetPtr[3];
    }

    retValue.sprintf("%02x%02x%02x%02x", targetBuf[0], targetBuf[1], targetBuf[2], targetBuf[3]);
    return retValue;
}

QString CUtil::hexaToAsciiString(const uint hexaData, CUtil::ENDIAN endian)
{
    char* ascStr = (char*)&hexaData;

    QString ret;

    if (endian == ENDIAN_BIG)
    {
        ret.append(ascStr[3]);
        ret.append(ascStr[2]);
        ret.append(ascStr[1]);
        ret.append(ascStr[0]);
    }
    else
    {
        ret.append(ascStr[0]);
        ret.append(ascStr[1]);
        ret.append(ascStr[2]);
        ret.append(ascStr[3]);
    }


    return ret;
}

 

함수설명

 

예를들어 데이터를 int(4byte)에 담아서 뭔가를 한다고 하자 근데 1byte마다 hexa형태의 데이터를 사용해야 할 때가있다.

 

가령 데이터가

 

 

0x31313131 < - 요런식으로

 

첫번째함수는

0x31313131를 -> 고대로 "31313131" 로 바꾸어준다

 

두번째함수는

0x31313131를 -> 아스키형태의 String으로 "1111"로 바꾸어준다. 필요한사람 가져다쓰세요~

 

함수는 uint로 했지만 다른 메모리를 사용하고 싶다면 적당히 오버로딩해서 여러타입을 넣어서쓰면된다.

요즘 친구들과 이야기를 나누다보면 기본 기초가 안되어있는 경우가 좀 많은 것 같다.

 

나 역시 그렇다고 생각한다. 회사에 급이랄까...

 

먹고 사는데 바쁜 회사는 기본 기초 이런거에 신경 안 쓰는 회사가 되게많다..

 

대기업일수록 IT회사일수록 SW기초를 되게 따진다. 근데 알고리즘 개발능력과는 또 다른 영역 인 것같다.

 

소위 말하는 설계의 영역이랄까 클린코드 책을 읽으면 초반부에 나오는 내용인데

 

업무하는 시간 8시간을 100%라고 놓았을때 코드를 읽는시간이 90%고 작성하는 시간이 10%란다..

 

극히 공감가는 내용이다. 코딩을 하더라도 내가 어제 어디까지 코딩했는지 이전 코드를 읽는 작업부터 시작하니까

 

요즘 IT뜬다고 비전공자나 유사관련 학과가 SW개발하는 경우가 많다. 그들의 열정은 존중한다.

나보다 훨씬 실력있고 뛰어난 사람도 많다고 생각한다. 근데 그렇지 않은 사람도 많다.

 

C++를 개발하는 사람이라면 effective c++(스콧마이어스), effective modern c++정도는 읽어보길 권장한다.

기본적인 OOP의 개념과 문법을 이해했다면 분명 도움될것이라 생각한다.

 

그리고 이글을 대학갓 졸업한 새내기가 보고있다면 기본기초를 제대로 가르쳐주는 회사를 가라.

회사를 선택할때 기준점 중 하나라고 생각하면 좋다.

 

그냥그렇다구 -3- 

 

#include <QTimer>
#include <QDebug>
#include <QThread>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "zbar.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
      , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->mTimer = new QTimer(this);

    connect(this->mTimer, &QTimer::timeout, this, [this]
            {
                cv::Mat matrix;
                this->mCap >> matrix;

                if(matrix.data == nullptr)
                    return ;

                QImage cvImg  = QImage((uchar*)matrix.data, matrix.size().width, matrix.size().height, matrix.step, QImage::Format_RGB888);//0xffRRGGBB (24bit)
                auto swapedImage = cvImg.rgbSwapped();

                QPixmap image(QPixmap::fromImage(swapedImage));
                ui->label->setPixmap(image);
            });
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked() noexcept
{
    qDebug() << this->mCap.open(0);

    this->mTimer->start(50);
}
void sharpen(const cv::Mat &image, cv::Mat &result);


void MainWindow::on_btnQRRead_clicked()
{
    cv::Mat matrix;
#if 0 //static
    matrix = cv::imread("C:/YourFullPath/YourFileName.png"); // or mTemp
#else //camera
   this->mCap >> matrix;
#endif

    if(matrix.data == nullptr)
        return ;

    QStringList resultList;

    zbar::ImageScanner scanner;
    scanner.set_config(zbar::ZBAR_QRCODE, zbar::ZBAR_CFG_ENABLE , 1);

    cv::Mat imGray;
    cv::cvtColor(matrix, imGray, cv::COLOR_BGR2GRAY);

    zbar::Image image(imGray.cols, imGray.rows, "Y800", (uchar *)imGray.data, imGray.cols * imGray.rows);
    qDebug() << scanner.scan(image);

    for(auto symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol)
    {
        QString result;
        result = QString::fromStdString(symbol->get_data());
        resultList.push_back(result);
    }
    cv::imshow("test", imGray);

    qDebug() << resultList;
}

http://naver.me/IF6payOn

 

네이버 클라우드

소중한 폰 사진을 안전하게 보관하고, 함께보기로 가족, 친구들과 손쉽게 공유해 보세요!

cloud.naver.com

소스와 lib 묶음은 해당링크 참조

 

os : windows 10 - 64bit

 

compile kit : mingw32 bit / qt 5.11.3 /zbar lib /opencv 사용

 

 

 

 

 

 

 

 

 

 

# qr 데이터 사용시 주의 사항

# qr의 회전 및 좌우반전에 인식률이 크게 영향을받음

다들 알다 싶이 프로그램의 실수 표현은 정확한 소수점 데이터가 나오는게 아니다.

 

부동소수점 표현방식의 한계인데 

 

int test1 = 0;

double test2 = 0.0;

 

 

if(test1 == test2) //??

   //과연 true일까?

 

눈치 챈 사람도 있겠지만 true가 나올수도 나오지 않을 수도있다.(컴파일러마다 다름)

 

그래서 qt에서는 

qFuzzyCompare()

qFuzzyIsNull() 

 

두개의 함수를 지원한다.

첫번째는 데이터 a와 데이터 b를 비교하고

두번째는 데이터 a와 상수 0을 비교한다.

 

꼭 실수형 비교할때 두함수를 쓰자. ㅎㅎ

#include <QBitArray>

QBitArray charToBitArray(char bits)
{
    QBitArray array(8);
    return array.fromBits(&bits, 8);
}

 

+ Recent posts