ImageByte Array 로 변환 (Image -> Byte[])

Byte Array 을 Image 로 변환 (Byte[] -> Image)

 

 

------------------------------------------------------------------------------------------------------------------

 

 

 

 

위 프로그램은 이미지 파일을 읽어서 Image 를 보여주고,

이 Image 를 Byte[ ] 로 변환 하고,

다시 Byte[ ] 을 Image 로 변환시켜주는 프로그램입니다.

 

아래 이미지처럼 실제 이미지 파일의 경로를 입력해주고,

이 이미지 파일을 읽어서 Picture Box 1 에 보여주도록 하겠습니다.

 

 

 

 

우측 상단에 위치한 File To Image 버튼 이벤트는 아래처럼 구현되어 있습니다.

 

 

 

 

File To Image 버튼을 클릭한 결과입니다.

 

 

 

 

이번에는 Image To Byte[ ] 버튼을 눌러서 Picture Box 1 의 이미지를 Byte[ ] 로 변환해보도록 하겠습니다.

Image To Byte[ ] 버튼은 아래처럼 구현되어 있습니다.

 

 

 

 

Image To Byte[ ] 버튼을 클릭해서 Byte[ ] 을 얻고 RichTextBox 에 Byte[ ] 이라는 것만 표시했구요.

Byte[ ] 의 값은 RichTextBox 에 임시로 저장해두었습니다.

 

 

 

 

실제 이미지의 대한 Byte[ ] 의 값은 이렇습니다.

 

 

 

이번엔 이 Byte[ ] 을 토대로 다시 Image 로 변환해보겠습니다.

Byte[ ] to Image 버튼 이벤트는 아래처럼 구현되어 있습니다.

 

 

 

 

Byte[ ] 을 다시 Image 로 변환했습니다.

 

 

 

 

 

 

 

 

Posted by 오늘은 휴가
,

 

 

프로그램 내에서 파일 탐색기를 (explorer.exe) 를 이용하여 FTP 폴더 연동하기

 

 

------------------------------------------------------------------------------------------------------------------

 

 

 

 

 

위 프로그램은 IP 와 PORT 를 입력한 후, Go to FTP Folder 버튼을 누르면 FTP 폴더를 연동시켜주는 프로그램입니다.

 

Go to FTP Folder 버튼 이벤트는 아래처럼 구현되어 있구요.

 

 

 

 

 

 

(파일 탐색기 (explorer.exe) 프로그램에 매개변수로 FTP 경로를 넣어주고 실행을 시킴)

 

Go to FTP Folder 버튼을 클릭하면, 아래 이미지처럼 로그인을 해야만 접속이 가능하다고 나옵니다.

 

 

 

 

 

 

버튼을 클릭할 때마다 매번 FTP 로그인 계정 정보를 직접 입력을 해야하는 번거로움이 있는데요.

 

이를 해결할 수 있는 방법이 있습니다.

 

우선 FTP 접속 계정 정보 (ID, Password) 를 아래처럼 추가시켜줍니다.

 

 

 

 

 

 

그리고 버튼 클릭 이벤트 내용에서 FTP 경로를 아래 포맷대로 변경해줍니다.

 

 

ftp://[USER]:[PWD]@[IP]:[PORT]

 

ftp://ftpuser:1234@192.168.50.111:8041

 

 

ftpuser  FTP 로 접속할 ID 이고, 1234 Password 입니다. 그리고

: ID 와 PWD 를 구분하고,  @ 계정정보 (ID 와 PWD) 와 IP 주소를 구분합니다.

 

(주의사항 @는 구분자이기때문에 Password 에 @가 포함된다면 정상적으로 실행이 불가합니다.)

 

 

 

 

 

 

이제 버튼을 누르면 아래 이미지처럼 로그인 과정을 생략하고

 

바로 FTP 폴더로 연동되는 것을 확인할 수 있습니다.

 

 

 

 

 

 

Posted by 오늘은 휴가
,

DataTable 내 특정 컬럼의 값들을 배열로 얻고 싶다면?

LINQ (Language Integrated Query, 통합 질의 언어) 사용하기

 

 

 

위와 같은 DataTable '과일' 이 있다.

 

------------------------------------------------------------------------------------------------------------------

 

 

[ 1. 과일의 이름을 배열로 얻기 ]

 

- dt.Select().Select(x => x["이름"])              // 굳이 x 가 아니어도 상관없음

- dt.Select().Select(x => x["이름"])             // DataTable 내 특정 컬럼의 이름으로 직접 접근

- dt.Select().Select(x => x[1]                       // DataTable 내 특정 컬럼의 인덱스로 접근 (번호(0) / 이름(1) / 원산지(2))

- LINQ 로 얻은 배열은 Object[] 이기때문에 별도의 변환작업이 필요함 (Casting 작업)

 

1
2
3
           

           // Column  '이름 Row 14건을 stirng[]  반환

           object[] arrObj = dt.Select().Select(x => x["이름"]).ToArray();

           string[] arrStr = arrObj.Cast<string>().ToArray();

 
cs

 

 

 

 

[ 2. 과일의 이름을 배열로 얻기 (중복제외) ]

- dt.Select().Select(x => x["이름"]).Distinct().ToArray();  // 중복제외

1

2

3

            // Column  '이름 Row 14건을  중복을 제외한 값들을 

            // stirng[]  반환 (메론사과바나나딸기)

            object[] arrObj = dt.Select().Select(x => x["이름"]).Distinct().ToArray();

            string[] arrStr = arrObj.Cast<string>().ToArray();

cs

 

 

 

 

 

 

 

 

 

 

[ 3. 과일의 이름을 배열로 얻기 (중복제외 / 조회조건 추가) ]

- dt.Select().Where(r => r["원산지"].ToString() == "경기도").Select(x => x["이름"]).Distinct().ToArray();

=> "원산지" 에는 컬럼이름 또는 컬럼의 인덱스 값을 입력

=> "경기도" 에는 조건에 해당하는 또는 변수를 입력

 

 

1

2

3

            // Column  '이름 Row 14건을  중복을 제외한 값들  원산지가 경기도인 값들을 

            // stirng[]  반환 (메론사과딸기)

            object[] arrObj = dt.Select().Where(r => r["원산지"].ToString() == "경기도")

                                                    .Select(x => x["이름"]).Distinct().ToArray();

            string[] arrStr = arrObj.Cast<string>().ToArray();

Colored by Color Scripter

cs

 

 

 

 

 

 

 

 

 

 

 

 

[ 4. 과일의 이름을 배열로 얻기 (중복제외 / 조회조건 추가 / 순서정렬)

- dt.Select().Where(r => r["원산지"].ToString() == "경기도").OrderBy(p => p["이름"].Select(x => x["이름"]).Distinct().ToArray();

=> OrdeBy(p => p["이름"]                        // 이름 컬럼의 데이터들을 오름차순으로 정렬

=> OrderByDescending(p => p["이름"]   // 이름 컬럼의 데이터들을 내림차순으로 정렬

1

2

3

            // Column  '이름 Row 14건을  중복을 제외한 값들  원산지가 경기도인 값들을 

            // 오름차순하여 정렬  stirng[]  반환 (딸기메론사과)

            object[] arrObj = dt.Select().Where(r => r["원산지"].ToString() == "경기도")

                                                    .OrderBy(p => p["이름"]).Select(x => x["이름"]).ToArray();

            string[] arrStr = arrObj.Cast<string>().ToArray();

Colored by Color Scripter

cs

 

 

 

 

 

 

 

 

 

 

'[ C# ] > ㄴ Tips' 카테고리의 다른 글

[C#] Image To Byte Array, Byte Array To Image  (0) 2019.07.26
[C#] FTP 폴더 연동하기  (0) 2019.07.24
Posted by 오늘은 휴가
,

 

InvalidOperationException

자신이 만들어진 스레드가 아닌 스레드에서 액세스되었습니다.

 

------------------------------------------------------------------------------------------------------------------

 

[ 1. 발생원인 ]

- 여러 Thread 에서 하나의 컨트롤에 접근하는 경우

- Main Thread 가 관리하고 있는 Object 에 다른 Thread 가 접근하는 경우 (Main Thread 는 접근 가능, 다른 Thread 는 접근 불가능)

 

 

[ 2. 현상확인 ]

- MainForm 에 Label 과 Button 이 있음

- Label (uiLab_Value) 의 초기값 = 0

- Button (Thread Start) 에 클릭 이벤트 연동

- Thread 객체 t

 

* 프로그램 실행화면

 

* Button (Thread Start) 클릭 이벤트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        private void UiBtn_ThreadStart_Click(object sender, EventArgs e)
        {
            // Thread 가 실행중이면, 종료
            if (t != null && t.IsAlive == true)
            {
                t.Abort();
                t.Join();
                = null;
            }
 
            // Thread 생성 및 Thread 가 실행할 함수(UpNumber) 연동
            t = new Thread(new ThreadStart(UpNumber));
 
            // Thread 시작
            t.Start();
        }
cs

 

* Thread 가 실행할 UpNumber( ) 메서드

1
2
3
4
5
6
7
8
9
        private void UpNumber()
        {
            while (true)
            {
                // 현재 값을 증가시킴
                int nextVal = Convert.ToInt32(this.uiLab_Value.Text) + 1;
                this.uiLab_Value.Text = nextVal.ToString();
            }
        }
cs

 

* Button (Thread Start) 을 누르면,

아래와 같이 Thread 가 실행한 UpNumber( ) 메서드 내에서 크로스 스레드 예외가 발생

 

 

[ 3. 해결방법 ]

- 다른 Thread 에서 접근하려는 Object 에 Invoke 를 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        private void UpNumber()
        {
            while (true)
            {
                // 현재 값을 증가시킴
                int nextVal = Convert.ToInt32(this.uiLab_Value.Text) + 1;
                //this.uiLab_Value.Text = nextVal.ToString();
 
                // Invoke 를 이용하여 해당 Object 에 대한 접근 권한을 얻기
                // uiLab_Value 객체에 접근하기위해 Invoke 가 요구된다면
                if (this.uiLab_Value.InvokeRequired == true)
                {
                    this.uiLab_Value.Invoke((MethodInvoker)delegate
                    {
                        this.uiLab_Value.Text = nextVal.ToString();
                    });
                }
                else
                {
                    this.uiLab_Value.Text = nextVal.ToString();
                }
            }
        }
cs

 

 

[ 4. 실행결과 ]

 

 

* 다른 Thread 가 실행 중에, 해당 화면이 종료될 경우 예외처리 필수

1
2
3
4
5
6
7
8
9
10
11
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 스레드가 살아있으면 (동작하고 있는 중이면)
            if (t != null && t.IsAlive == true)
            {
                // 스레드 중지
                t.Abort();
                t.Join();
                = null;
            }
        }
cs

 

 

------------------------------------------------------------------------------------------------------------------

 

[ 요약 ]

- 크로스 스레드 예외가 발생하면, Invoke 를 사용하여 해결!!

Posted by 오늘은 휴가
,