이 글은 제가 검색하는 과정도 포함되어 있습니다.

윈도우에서 파일의 정보를 가져오기 위해서 기본적으로 사용하고 있는 클래스는 FileInfo 입니다.
하지만 어느 카메라로 찍었는지, 어디서 찍었는지 등에 대한 정보를 확인하기 위해서는 MetaData를 확인해야 합니다.

그래서 구글에서 검색을 시작하였습니다. 처음으로 검색한 단어는 "read image metadata c#" 입니다.
관련 코드를 쉽게 찾을 수 있었습니다.

출처: Reading data metadata from JPEG, XMP or EXIF in C#
주소: https://stackoverflow.com/questions/2280948/reading-data-metadata-from-jpeg-xmp-or-exif-in-c-sharp?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

위 제공된 코드는 아래와 같습니다.

    public string GetDate(FileInfo f)
    {
        using(FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            BitmapSource img = BitmapFrame.Create(fs);
            BitmapMetadata md = (BitmapMetadata)img.Metadata;
            string date = md.DateTaken;
            Console.WriteLine(date);
            return date;
        }
    }

그래서 Visual Studio 에서 바로 실행해 보기로 했습니다.

1. Visual Studio(2017 기준) 를 실행하고 새로운 프로젝트를 생성합니다.
상단 메뉴의 파일(F) - 새로 만들기(N) - 프로젝트(P) 를 선택합니다.

좌측 메뉴에 Visual C# - Windows 클래식 바탕화면을 선택하고 가운데 메뉴에 Windows Forms 앱(,net Framework)를 선택합니다.
앱 이름은 WindowsFormsGetMetaData 로 정하겠습니다. 폴더는 원하는 위치를 지정해 주세요. 아래 그림과 같이 설정이 끝났으면 확인 버튼을 클릭합니다.

폼 이름 및 크기를 바꿔볼께요.
폼을 선택하고 속성 도구를 열고 Text와 Size 속성을 바꿉니다.
(Name): Form1 - Text: 메타데이터 읽기 / Size: 400, 600

다음에 컨트톨을 추가해 보겠습니다.
도구 상자탭을 선택하고 원하는 도구 상자를 드래그해서 폼 안에 넣으면 됩니다.

저는 아래와 같이 넣었습니다.

각 도구의 주요 속성은 다음과 같습니다.

버튼(Button) - (Name): button1 / Location: 20, 20 / AutoSize: False / Size: 75, 23 / Text: 파일 선택
라벨(Label) - (Name): label1 / Location: 20, 60 / AutoSize: True / Size: 73, 12(자동으로 설정됨) / Text: 선택된 파일:
라벨(Label) - (Name): label2 / Location: 100, 60 / AutoSize: True / Size: 29, 12(자동으로 설정됨) / Text: 없음
자료보기창(DataGridView) - (Name): dataGridView1 / Location: 20, 90 / AutoSize: False / Size: 350, 450

외형을 완성했으면 이제 프로그래밍을 해보겠습니다.
폴더 선택 버튼을 더블클릭하면 자동으로 이벤트가 추가되고 코드보기 화면으로 전환됩니다.

우선 버튼 클릭 부분에는 OpenFileDialog 를 생성해서 파일이 있으면 파일명을 MessageBox에서 보여주도록 코드를 작성하였습니다.

버튼클릭 이벤트 아래쪽에 위에서 찾은 코드를 복사합니다. 우선 FileInfo 는 using System.IO; 를 활용해서 불러옵니다.
이렇게 하면 아래 그림과 같이 오류가 발생합니다.

이제부터 오류가 발생하는 부분을 찾아보겠습니다.

BitmapSource 를 구글에서 찾아보니 아래 링크에서 해당 클래스 정보를 확인할 수 있습니다.
제목: BitmapSource 클래스
네임스페이스:   System.Windows.Media.Imaging
어셈블리:  PresentationCore(PresentationCore.dll에 있음)
https://msdn.microsoft.com/ko-kr/library/system.windows.media.imaging.bitmapsource(v=vs.110).aspx

위 내용을 보면 PresentationCore 어셈블리를 추가하면 될 것으로 보입니다.
아래 그림과 같이 솔루션 탐색기에서 참조에 마우스를 대고 오른쪽 버튼을 클릭한 후에 참조 추가 메뉴를 클릭합니다.

오른쪽 어셈블리에서 프레임워크를 선택하고 오른쪽 검색창에 "presentationcore" 를 검색하면 결과가 하나만 나타납니다.
추가하려면 이름 옆에 있는 체크박스를 클릭해서 체크표시 한 후에 확인 버튼을 클릭하면 PresentationCore 어셈블리를 사용할 수 있습니다.

그리고 코딩 파일에 "using System.Windows.Media.Imaging;" 을 입력해서 해당 네임 스페이스를 불러옵니다.
그러면 BitmapSource, BitmapFrame, BitmapMetadata 사용이 가능합니다. 하지만 여전히 "BitmapFrame.Create" 부분에서 오류가 발생하네요.
오류 내용은 다음과 같습니다.

'Freezable' 형식이 참조되지 않은 어셈블리에 정의되었습니다. 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 어셈블리에 참조를 추가해야 합니다.

이 부분도 동일하게 해결 가능합니다.

솔루션 탐색기에서 참조에 마우스를 대고 오른쪽 버튼을 클릭한 후에 참조 추가 메뉴를 클릭합니다.
오른쪽 어셈블리에서 프레임워크를 선택하고 오른쪽 검색창에 "windowsbase" 를 검색하면 결과가 하나만 나타납니다.
추가하려면 이름 옆에 있는 체크박스를 클릭해서 체크표시 한 후에 확인 버튼을 클릭하면 WindowsBase 어셈블리를 사용할 수 있습니다.

이제 오류는 다 잡았습니다. 지금부터는 원하는 정보를 가져와서 DataGridView에 보여주면 되겠네요.
메서드1. 위에 제공된 코드를 아래와 같이 수정합니다. 기존 코드는 파일을 만든 날짜만 확인하였는데 전 확인 가능한 모든 속성을 가져오겠습니다.

        /// <summary>
        /// 선택한 파일의 메타데이터를 DataTable 형식으로 보냅니다.
        /// </summary>
        /// <param name="f">자료를 가져올 파일의 FileInfo를 입력합니다.</param>
        /// <returns></returns>
        private DataTable GetDate(FileInfo f)
        {
            using (FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) // 선택된 파일의 FileStream 을 생성합니다. 
            {
                DataTable dt1 = new DataTable(); // 새로운 DataTable을 생성합니다.
                dt1.Columns.Add("attribute"); // 속성 이름을 저장합니다.
                dt1.Columns.Add("value"); // 속성 값을 저장합니다.

                BitmapSource img = BitmapFrame.Create(fs); // 선택된 파일의 FileStream 를 활용하여 BitmapSource 를 생성합니다.
                BitmapMetadata md = (BitmapMetadata)img.Metadata; // 

                // BitmapMetadata 에서 제공하는 모든 속성 값을 불러옵니다. 시작
                // https://msdn.microsoft.com/ko-kr/library/system.windows.media.imaging.bitmapmetadata(v=vs.110).aspx
                dt1.Rows.Add("ApplicationName", md.ApplicationName);
                dt1.Rows.Add("Author", md.Author);
                dt1.Rows.Add("CameraManufacturer", md.CameraManufacturer);
                dt1.Rows.Add("CameraModel", md.CameraModel);
                dt1.Rows.Add("CanFreeze", md.CanFreeze);
                dt1.Rows.Add("Comment", md.Comment);
                dt1.Rows.Add("Copyright", md.Copyright);
                dt1.Rows.Add("DateTaken", md.DateTaken);
                dt1.Rows.Add("DependencyObjectType", md.DependencyObjectType);
                dt1.Rows.Add("Dispatcher", md.Dispatcher);
                dt1.Rows.Add("Format", md.Format);
                dt1.Rows.Add("IsFixedSize", md.IsFixedSize);
                dt1.Rows.Add("IsFrozen", md.IsFrozen);
                dt1.Rows.Add("IsReadOnly", md.IsReadOnly);
                dt1.Rows.Add("IsSealed", md.IsSealed);
                dt1.Rows.Add("Keywords", md.Keywords);
                dt1.Rows.Add("Location", md.Location);
                dt1.Rows.Add("Rating", md.Rating);
                dt1.Rows.Add("Subject", md.Subject);
                dt1.Rows.Add("Title", md.Title);
                // BitmapMetadata 에서 제공하는 모든 속성 값을 불러옵니다. 끝

                return dt1;
            }
        }


매서드2. 위에서 제공된 결과를 DataGridView 컨트롤에서 볼 수 있도록 가져옵니다.

        /// <summary>
        /// 선택한 폴더의 파일 목록을 가져와서 DataGridView 도구에 보여줍니다.
        /// </summary>
        /// <param name="dt1">선택한 폴더의 파일 목록이 들어있는 DataTable을 입력합니다.</param>
        /// <param name="dgv1">결과를 출력할 DataGridView를 선택합니다.</param>
        private void ShowDataFromDataTableToDataGridView(DataTable dt1, DataGridView dgv1)
        {
            dgv1.Rows.Clear(); // 이전 정보가 있을 경우, 모든 행을 삭제합니다.
            dgv1.Columns.Clear(); // 이전 정보가 있을 경우, 모든 열을 삭제합니다.

            foreach (DataColumn dc1 in dt1.Columns) // 선택한 파일 목록이 들어있는 DataTable의 모든 열을 스캔합니다.
            {
                dgv1.Columns.Add(dc1.ColumnName, dc1.ColumnName); // 출력할 DataGridView에 열을 추가합니다.
            }

            int row_index = 0; // 행 인덱스 번호(초기 값)
            foreach (DataRow dr1 in dt1.Rows) // 선택한 파일 목록이 들어있는 DataTable의 모든 행을 스캔합니다.
            {
                dgv1.Rows.Add(); // 빈 행을 하나 추가합니다.
                foreach (DataColumn dc1 in dt1.Columns) // 선택한 파일 목록이 들어있는 DataTable의 모든 열을 스캔합니다.
                {
                    dgv1.Rows[row_index].Cells[dc1.ColumnName].Value = dr1[dc1.ColumnName]; // 선택 행 별로, 스캔하는 열에 해당하는 셀 값을 입력합니다.
                }
                row_index++; // 다음 행 인덱스를 선택하기 위해 1을 더해줍니다.
            }

            foreach (DataGridViewColumn drvc1 in dgv1.Columns) // 결과를 출력할 DataGridView의 모든 열을 스캔합니다.
            {
                drvc1.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; // 선택 열의 너비를 자동으로 설정합니다.
            }
        }

위에서 만든 2개의 매서드를 활용하여 버튼클릭 이벤트를 아래와 같이 수정합니다.

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog(); // 새로운 OpenFileDialog 를 생성합니다.
            if (openFileDialog1.ShowDialog() == DialogResult.OK) // 파일이 정상적으로 선택되었을 경우에 동작합니다.
            {
                label2.Text = openFileDialog1.FileName; // 선택된 파일을 label2에 출력합니다.
                FileInfo f = new FileInfo(openFileDialog1.FileName); // 파일 전체 경로로 해당 파일의 FileInfo를 생성합니다.
                DataTable dt_metadata = GetDate(f);
                ShowDataFromDataTableToDataGridView(dt_metadata,dataGridView1);
            }
        }

전체 코드는 아래와 같습니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.Windows.Media.Imaging;

namespace WindowsFormsGetMetaData
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog(); // 새로운 OpenFileDialog 를 생성합니다.
            if (openFileDialog1.ShowDialog() == DialogResult.OK) // 파일이 정상적으로 선택되었을 경우에 동작합니다.
            {
                label2.Text = openFileDialog1.FileName; // 선택된 파일을 label2에 출력합니다.
                FileInfo f = new FileInfo(openFileDialog1.FileName); // 파일 전체 경로로 해당 파일의 FileInfo를 생성합니다.
                DataTable dt_metadata = GetDate(f);
                ShowDataFromDataTableToDataGridView(dt_metadata,dataGridView1);
            }
        }

        /// <summary>
        /// 선택한 파일의 메타데이터를 DataTable 형식으로 보냅니다.
        /// </summary>
        /// <param name="f">자료를 가져올 파일의 FileInfo를 입력합니다.</param>
        /// <returns></returns>
        private DataTable GetDate(FileInfo f)
        {
            생략(매서드1)
        }

        /// <summary>
        /// 선택한 폴더의 파일 목록을 가져와서 DataGridView 도구에 보여줍니다.
        /// </summary>
        /// <param name="dt1">선택한 폴더의 파일 목록이 들어있는 DataTable을 입력합니다.</param>
        /// <param name="dgv1">결과를 출력할 DataGridView를 선택합니다.</param>
        private void ShowDataFromDataTableToDataGridView(DataTable dt1, DataGridView dgv1)
        {
            생략(매서드2)
        }

    }
}

이제 실행해 보겠습니다.
실행하면 다음과 같이 나타납니다.

메타데이터가 있는 그림파일을 선택하면 다음과 같이 읽어오는 것을 볼 수 있습니다.

하지만 윈도우 탐색기에서 파일 선택해서 마우스 오른쪽 버튼 클릭 후 속성 클릭 후 자세히 보기에 나타나는 정보는 기본적으로 제공하는 MetaData 보다 많은 것을 확인할 수 있습니다. 이 부분에 대해 아시는 분 있으면 댓글 남겨주세요. 저도 관련 정보를 더 찾아보도록 하겠습니다.

감사합니다.

유튜브 영상을 다운로드 받을 수 있는 프로그램 중에서 제가 사용중인 프로그램을 소개합니다.

제가 이 글을 작성하는 이유는 저 조차도 계속 검색으로 프로그램을 찾으면 제가 원하지 않는 프로그램을 설치하게 되는 경우가 발생하기 때문입니다.

구글에서 youtube downloader 를 검색하면 다양한 프로그램이 나오는데요.
처음에는 무조건 가장 위에있는 프로그램을 무조건 설치했었습니다. 그러다가 맘에 안들면 바로 지우거나 다른 프로그램을 찾아서 설치를 하게 됩니다.

몇 가지 프로그램을 써봤는데 현재 가장 만족하면서 사용중인 프로그램 다음과 같습니다.

https://youtubedownloader.com/

아래 스크린샷은 홈페이지에서 퍼왔습니다.

Download MP4

사용방법은 간단합니다.

1. 사이트 메인에 있는 Download for Free 버튼을 클릭해서 프로그램을 다운로드합니다.(주의:맥 버전은 없습니다.)

2. 다운로드 받은 파일을 실행해서 프로그램을 설치합니다.

3. 프로그램을 실행합니다.

4. 유튜브 영상 주소를 복사합니다. 그러면 프로그램에 자동으로 추가됩니다.

5. 다운로드 받을 화질을 선택한 후 다운로드 버튼을 클릭합니다.
    - 컴퓨터 내부에서 볼 때는 1080p, 컴퓨터 등 큰 화면에서의 스트리밍을 720p, 휴대폰 스트리밍 용으로는 480p 정도가 적당하다고 생각합니다.

프로그램 이름이 "Youtube Downloader" 인 프로그램이 여러개다 보니 프로그램 이름을 부르기 좀 그렇네요.

플레이리스트 다운로드 등 프리미엄 기능은 유료이지만 영상을 하나하나 다운로드 받기에 개인적으로 가장 편하다고 생각합니다.

다른 의견이 있으면 댓글 주세요.

감사합니다.

'유용한 정보 > 프로그램' 카테고리의 다른 글

반응형 스킨 설치하기 FastBoot v1.6.2  (0) 2018.06.07
SyntaxHighlighter 사용하기  (0) 2018.06.04

mysql 쿼리문을 활용하여 기본적인 DB, Table 생성, 자료 쓰기 및 읽기 명령어를 소개합니다.

1. DB 생성하기

[문법]
create database DB이름
[예제]
create database test #이름이 test인 DB 생성

2. Table 만들기

[문법]
create table Table이름(열1이름 열1형식, 열2이름 열2형식, ...);
[예제]
create table humaninfo(name varchar(50), yearmonthday varchar(8), age int, address varchar(200)); #이름이 humaninfo인 Table생성
#열1이름: name, 열1형식: 글자(50자이내)
#열2이름: yearmonthday, 열2형식: 글자(8자이내)
#열3이름: age, 열3형식: 정수
#열4이름: name, 열4형식: 글자(200자이내)

3. Table에 자료 쓰기

[문법]
insert into Table이름 values(열1값, 열2값, ...);
[예제]
insert into hummaninfo values('강인한', '19840831', 33, '서울시 강서구 화곡동'); #hummaninfo Table에 자료 쓰기
# name: 강인한, yearmonthday: 19840831, age: 33, address: 서울시 강서구 화곡동
insert into hummaninfo values('김길동', '19920910', 25, '경기도 김포시 풍무동'); #hummaninfo Table에 자료 쓰기
# name: 김길동, yearmonthday: 19920910, age: 25, address: 경기도 김포시 풍무동

4. Table 자료 읽기

[문법]
select * from Table이름;
[예제]
select * from hummaninfo; # hummaninfo Table의 모든 자료 읽기

감사합니다.

저는 최근에 시놀로지(synology) NAS를 구매하였습니다.


하드디스크에 있는 방대한 자료들을 공유하고 외부 컴퓨터, 노트북, 태블릿, 휴대폰 등 어디서든지 확인하기에 좋은 장비입니다.


구매하고 보니 이 뿐만 아니라 웹서버, PHP, DB 등 다양한 기능을 제공하고 있어 프로그래밍을 할 때에도 유용하게 사용하게 되었습니다.


그런데 php 7.0을 설치하고 간단한 DB 접속을 위한 코드를 작성 후 실행해 보니 실행이 안되었습니다. 처음에는 코드 문제인줄 알았는데 로컬 컴퓨터에 설치한 php에서는 잘 실행 되더라고요... 그래서 원인이 나스에 설치된 php에 문제가 있지 않을까 찾아봤습니다.

결과는 적중했습니다.

시놀로지 포험 페이지: https://forum.synology.com/enu/viewtopic.php?t=50976


보안 때문인지 php 기본 설정은 mysqli 등의 함수 사용을 못하도록 되어있습니다.


이 설정을 풀어보겠습니다.


1. diskstation 에 접속합니다.


2. 로그인을 합니다.


3. 오른쪽 상단에 있는 메인메뉴를 클릭합니다.


4. Web Station 을 클릭해서 실행합니다.


5. 좌측 메뉴의 PHP 설정에 들어갑니다.


6. 사용중인 PHP 버전(저는 PHP 7.0을 사용하고 있습니다.)을 선택하고 편집 버튼을 클릭합니다.


7. 일반설정에서 Xdebug 활성화, 디스플레이 에러 활성화(오류가 발생할 경우 어디가 오류가 났는지 알려줍니다.)를 체크해 줍니다.


8. 확장 중 사용하기 원하는 내용을 선택합니다.(귀찮으면 다 선택합니다. 저도 다 선택했습니다.)


9. 확인 버튼을 클릭합니다.


10. 실행해 보면 기존에 안되던 코드가 실행이 될 것입니다. 실행이 계속 안될 경우 서비스를 재시작 해봅니다.(나스를 껏다 켜보세요)


감사합니다.

MySQL DB의 자료를 안드로이드 앱에서 사용하기 위해서는 중간에 php 또는 node.js 등의 서버 프로그래밍을 거쳐야 합니다.


그래서 이번에는 mysql DB 내용을 php를 활용하여 json 형식으로 가져오는 코딩을 해보겠습니다.


과정은 간단합니다. php 파일 하나만 만들면 되는데요.

php 코드는 다음과 같습니다.

<?php 
// DB 접속 
$con=mysqli_connect("DB접속도메인또는IP:포트(3306이아닌경우)","DB사용자ID","비밀번호","사용할DB"); 
// 접속 실패 시 메시지 나오게 하기 
if (mysqli_connect_errno($con)) 
{ echo "MySQL접속 실패: " . mysqli_connect_error(); } 

// 기본 클라이언트 문자 집합 설정하기 
mysqli_set_charset($con,"utf8"); 
// 쿼리문 실행, 결과를 res에 저장 
$res = mysqli_query($con, "select * from humaninfo"); 
// 결과를 배열로 변환하기 위한 변수 정의
$result = array(); 
// 쿼리문의 결과(res)를 배열형식으로 변환(result) 
while($row = mysqli_fetch_array($res)) 
{ array_push($result, array('name'=>$row[0],'yearmonthday'=>$row[1],'age'=>$row[2],'address'=>$row[3])); } 
// 배열형식의 결과를 json으로 변환 
echo json_encode(array("result"=>$result),JSON_UNESCAPED_UNICODE); 
// DB 접속 종료 
mysqli_close($con); 
?>

해당 파일을 서버에 올리고 실행하면 다음과 같이 결과가 출력됩니다.

{"result":[{"name":"강인한","yearmonthday":"19840831","age":"33","address":"서울시 강서구 화곡동"},{"name":"김길동","yearmonthday":"19920910","age":"25","address":"경기도 김포시 풍무동"}]}

이제 이 내용을 안드로이드에서 읽어오면 됩니다.

감사합니다.

+ Recent posts