워드프레스를 이용하다보면 호스팅을 이전해야하거나 여러 개의 워드프레스를 한 호스팅안에 설치할 경우가 생겨납니다.

그런데 이렇게 하나의 DB안에 여러 개의 워드프레스를 설치하기 위해서는 워드프레스 설치 당시 접두어인 wp_ 라고 입력되어있는 부분을 다르게 입력하고 설치하면 되지만 이미 다른 호스팅에서 설치되어있는 워드프레스를 옮겨와서 접두어(prefix)만 변경해서 이전하고 싶을 때가 있습니다.

 

워드프레스를 위한 DB 테이블 접두어 변경 방법

 

1. 일단 PhpMyAdmin 을 접속해서 변경하려는 wp_ 로 되어있는 테이블을 선택한 후 하단의 ‘테이블의 접두사를 교체‘를 누릅니다.

 

2. 아래 그림과 같이 변경전 접두어와 변경할 접두어를 입력하고 확인을 누릅니다.

 

3. 그러면 변경된 테이블들을 볼 수 있습니다.

 

4. wp-config.php 파일안의 $table_prefix  = ‘wp_’; 값을 변경한 접두어로 바꾼 후에 저장합니다.

 

5. DB 테이블에서  wp_options 이였던 테이블을 찾아 <보기>버튼을 누릅니다. 저 같은 경우 위에서 wp_를 hwp_로 바꾸었으니 hwp_options를 클릭하면 되는거죠.

 

 

6. 아마 30개씩 15페이지 정도의 옵션들이 나오게 되는데 여기서 약 3페이지정도에 가보면 wp_user_roles 라고 나올 겁니다. 이 것을 수정을 눌러 ‘option_name‘에 값을 변경된 접두어로 수정해서 넣은 뒤 실행을 누릅니다.

DB 테이블에서  wp_usermeta 이였던 테이블안에도 여전히 기존의 접두어들을 가진 meta_key들이 있기 때문에 여전히 ‘이 페이지에 접근할 권한이 없습니다.‘라고 나올 겁니다.

 

7. PhpMyAdmin에서 테이블 목록이 있는 곳에서 상단의 SQL 버튼을 누릅니다.

 

8. 입력창에 접두어가 변경된 wp_usermeta 테이블 이름을 넣고 meta_key 중에서 wp_를 찾아 바꾸려는 접두어로 변경하게 입력합니다.
저 같은 경우 wp_를 hwp_로 바꾸기 때문에 hwp_usermeta라고 썼고 meta_key 부분에도 hwp_로 바꾸게 입력하였습니다.

 

실행을 눌러 완료가 되면 아래처럼 결과 화면이 나옵니다.


----------



이후, prefix_options - sitesurl 값을 경로에맞게 변경을 해주어야한다. 


출처 : http://naminsik.com/blog/2829

mysqld_safe Directory ‘/var/run/mysqld’ for UNIX socket file don’t exists.

Published on  Author JFLeave a comment

This is about resetting the MySQL 5.7 root password in Ubuntu 16.04 LTS

You probably tried something like this:

sudo service mysql stop
mysqld_safe --skip-grant-tables &

And then got something like this (stangely, exists is misspelled in the output):

[1] 5599
2018-03-02T21:36:41.292413Z mysqld_safe Logging to syslog.
2018-03-02T21:36:41.294798Z mysqld_safe Logging to '/var/log/mysql/error.log'.
2018-03-02T21:36:41.296902Z mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists.

Then you tried to find the socket (takes a while):

sudo find / -type s

And /var/run/mysqld does not exist.

So you start mysql again and search and now it does exist!

sudo service mysql start
sudo find / -type s

[output:]
/run/mysqld/mysqld.sock
/run/dbus/system_bus_socket
/run/acpid.socket
/run/snapd-snap.socket
...

My guess is that mysql_safe can’t create the directory (which appears to be dynamically created when mysql starts). Solution:

sudo mkdir /var/run/mysqld 
sudo chown mysql:mysql /var/run/mysqld

Now run:

sudo service mysql stop
mysqld_safe --skip-grant-tables &
mysql -uroot mysql

--해결,

혹 아래와같은 문제가생긴다면 


When you get to the mysql prompt (don’t forget to change your pw before copy/pasting!!!):

UPDATE mysql.user SET authentication_string=PASSWORD('YOURNEWPASSWORD'), plugin='mysql_native_password' WHERE User='root' AND Host='%';

exit;

then

sudo mysqladmin -S /var/run/mysqld/mysqld.sock shutdown
sudo service mysql start

OTHER SOLUTION (means restarting MySQL a couple times!):

Note: in MySQL 5.7 you may find that my.cnf actually references config files elsewhere:

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

So in my case:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Under [mysqld] add:

skip-grant-tables

Close the file and restart mysql, then…

sudo service mysql restart
sudo mysql -uroot mysql
(use query above...)

Edit mysqld.conf again, remove the line, then restart MySQL

sudo service mysql restart

Good luck!



문제

알FTP와 같은 FTP로 파일 업로드를 할 때 

553 Could not create file 과 같은 오류가 뜨면서 파일을 업로드 할 수 없을 때가 있습니다. 

이것은 업로드 할 공간에대한 permission denied 문제 입니다. 


해결 방법

관리자 계정으로 ftp 서버에 접속해서 아래와 같은 명령어를 칩니다.

예를 들어 

파일을 업로드 할 사용자 계정이 ftpusername 이고 파일을 업로드할 디렉토리가 /var/www/html 일 때

chown -R ftpusername /var/www/html



출처: http://minooz.tistory.com/155 [우주 Blog]

{@

$args->module_srl = 모듈번호;

$output = executeQuery('document.getDocumentCount', $args);

}

{$output->data->count} 

출처 : https://www.xpressengine.com/tip/22827295




제 경우 XE 는 1.2 인가까지 쓰면서 이미지 슬라이더 등도 만들고 나름 노력했으나;

제로보드 4 가 여전히 더 편해서 다시는 안쓰기로 했었습니다.


그러다가 워드프레스로 옮겨탈까 하던 중에 제로보드 XE 가 버젼이 많이 업되어서 좋겠구나 하고 왔지요.


예약 게시판 하나 만들다가 뚜껑이 열려서 마구 헤맨 결과를 여기 적어 드립니다.


팁들로 하나씩 시리즈로 작성할게요.


참고로, 고수님들에게는 쓰레기 팁이고, 노가다로 그냥 자신의 스킨을 개조해서 쓰실 분들께는

간단하게 제작할 수 있는 팁입니다.


그러니, 고수분들은 가볍게 뒤로가기를 눌러주세요...



완전 초보분들도 따라하기 쉽게 쓸게요.




사용자 정의를 활용하여 폼 형식으로 개발하는 무식한 방법(1)


사용자 변수를 만든 XE가 초보 입장에서는 잘못이다.


우선 사용자 정의 변수를 만든 XE 가 이 뛰어난 기능을 엉망으로 쓰게 해둔 것에서 하나씩 보도록 하죠.



(XE 설치폴더)/modules/board/skins/해당스킨/write_form.html 파일에서 보게 되면,


<table cond="count($extra_keys)" class="et_vars exForm bd_tb">
  <caption><strong><em>*</em></strong> <small>: {$lang->is_required}</small></caption>
  <tr loop="$extra_keys=>$key,$val">
   <th scope="row"><em cond="$val->is_required=='Y'">*</em> {$val->name}</th>
     <td>
     {$val->getFormHTML()}
     </td>
  </tr>
</table>


이런 부분이 있을 것입니다.


이 부분에 간단히 코드를 추가합니다.


<table cond="count($extra_keys)" class="et_vars exForm bd_tb">
  <caption><strong><em>*</em></strong> <small>: {$lang->is_required}</small></caption>
  <tr loop="$extra_keys=>$key,$val">
   <th scope="row"><em cond="$val->is_required=='Y'">*</em> {$val->name}</th>
     <td>{$val->getFormHTML()}<br><br>
    module_srl : {$val->module_srl}, <br>
    idx : {$val->idx}, <br>
    name : {$val->name}, <br>
    type : {$val->type}, <br>
    default : {$val->default}, <br>
    desc : {$val->desc}, <br>
    is_required : {$val->is_required}, <br>
    search : {$val->search}, <br>
    value : {$val->value}, <br>
    eid : {$val->eid}, <br>
    total : {print_r($val)}
   </td>
  </tr>
</table>


이렇게 해주면 name 값을 처리하는 것이나 val 을 통해서 어떤 값들이 넘겨지게 되는 지를 확인 가능합니다.


그런데 여기에서 문제가 있죠.




<tr loop="$extra_keys=>$key,$val">
 

코드 상의 문제...라고 볼 수도 있습니다.


고수님들께서 보시기엔 아무 문제 없이 쉽게 해결하겠지만,


이렇게 되어 있어서 사용자 변수를 키값과 밸류값으로 그냥 뿌리는 형식으로 처리하면서,


 {$val->getFormHTML()}


이 함수에 넣고 그냥 폼으로 출력되게 하는 아주 간단한 구현을 해놓은 것입니다.


레이아웃이나, 메뉴 등에서만해도 끌올 등이 되는 등 아주 편한데,

이 값으로 해놓다보니, 우리 초보들은 사용자 정의를 입맛에 맞게 쓸 수가 없습니다.


간단히 설명해드리자면 idx 값에 숫자가 증가하면서 그게 인덱스가 되는 무식한 방법이죠.

그냥 사용자 정의 변수 1~n 번까지 루프 돌아서 뿌려버려~

이게 전부인 거죠.


일단 초보 단계에서 이걸 해결하는 방법은 위의 코드를 아예 주석으로 처리하고,

처리하기 전에 html 을 소스 보기로 보면서 무식하게 부분별로 형식을 지정해주는 거죠.


그런데 이렇게 한다고 해도 문제가 발생합니다.

우선, 수정을 눌렀을 때에 값 전달이 표기가 안됩니다.

그 다음으로는 입력시의 모양과 출력시의 모양이 달라집니다 -_-;


뭐, 출력시의 모양이 더 중요한 곳인 지, 입력시의 모양이 더 중요한 곳인 지는 각자의 판단에 달려있겠죠.


그래서 우선 위에 설명한 것처럼 idx 로 사용자 정의 변수를 쓰는 방식을 개조해야 합니다.



(XE설치경로)/modules/board/board.view.php 파일에서,


/**
* use context::set to setup extra variables
**/
  $oDocumentModel = getModel('document');
  $extra_keys = $oDocumentModel->getExtraKeys($this->module_info->module_srl);
  Context::set('extra_keys'$extra_keys);



이 부분을 찾아서 그 바로 아래에,

/**
* add extra variables to order(sorting) target
**/

if (is_array($extra_keys))

{
  

// extra_keys_map : extra_keys가 있을 때, 맵을 추가로 구성

   $extra_keys_map = array();

foreach($extra_keys as $val)

{

$extra_keys_map[$val->eid] = $val; // 맵에 값 할당 by diaimm

    $this->order_target[] = $val->eid;
}
      Context::set('extra_keys_map', $extra_keys_map); //맵을 view 로 전달해주는 거죠

}



이런 식으로 코드를 추가해둡니다.



아, 이런 이제서야 발견했습니다;; 확장 컴포넌트에 코드 입력이 있네요;

아놔 -_-;


// apply xml_js_filter on header
        $oDocumentController = getController('document');
        $oDocumentController->addXmlJsFilter($this->module_info->module_srl);


이 부분을 찾아서,


// if the document exists, then setup extra variabels on context
        if($oDocument->isExists() && !$savedDoc) {
            $extra_keys = $oDocument->getExtraVars();
            Context::set('extra_keys', $extra_keys);
 
            // 아래 코드에서 extra_keys 값이 있을 때 추가로 맵을 구성
            if (is_array($extra_keys))
            {
                $extra_keys_map = array();
                foreach($extra_keys as $val)
                {
                    $extra_keys_map[$val->eid] = $val;
                }
 
                Context::set('extra_keys_map', $extra_keys_map);
            }
            //여기까지
        }


그 밑에 이런 식으로 추가해주는 거죠.


이렇게 해주는 이유는 앞에서 말씀드린 것처럼 기본적으로 XE 에서는 사용자 정의 변수 자체를

아주 가볍게 보고 별 쓰잘데기 없지만 원하는 사람도 있으니까... 라는 정도로 코딩을 해둔 때문입니다.

(아, 이건 그냥 초보가 느끼는 심정 그대로 썼습니다 -0-)


그냥 보면 사용자 변수 이렇게 쓰이니까, 개발자 분들은 쉽게 사용하세요 정도로 안내해준 것인 듯 한데,

초보들에게는 때에 따라서 매우 필요한 기능이 제대로 활용하기 어려우니까 쪼끔 분노게이지 상승하는 거죠.


어쨌든, view 에서 index 를 쓰게 만들어서 idx 를 이용해서 변수를 순차로 매기는 것에서 순서를 무시하고도

값을 전달하고 받는 것에 문제가 없게끔 하는 첫 작업인 거죠.


그렇게 해주면 idx 가 아닌 사용자 정의 변수 이름 그대로 쓸 수 있습니다.


예를 들어서 사용자 변수 명을 testInput 라고 만들었다고 칩니다.


  <table cond="count($extra_keys)" border="1" cellspacing="0" summary="Extra Form" class="extraVarsList" width=100%>
   <caption><em>*</em> : {$lang->is_required}</caption>
   <tr>
    <th scope="row"><em>*</em> 테스트 입력</th>
    <td> <input type="text" name="extra_vars1" value="" class="text" />
      <p>여기가 설명 부분이 되겠죠</p>
    </td>
   </tr>


게시판에 글 쓰기를 하고 앞에서 말씀드린 부분을 주석처리하기 전에 보게 되면,

이런 식으로 소스코드를 볼 수 있을 것입니다.


따라서 주석 처리를 해주고 write_form.html 자체에 저 코드를 추가하면, 아무런 이상없이 쓰게 된다는 거죠.


저기서 보게 될 중요한 점은 어디에서 testInput 는 존재하지 않습니다.

즉, 변수명은 받기만하고 쓰잘데기없는 값처럼 둔갑하는 거죠.

extra_vars1 이라고 해서 여기 숫자만 중요합니다.


뭥미?


그렇다는 것은 사용자 변수를 20개 만들었는데...


아차! 하나 빼먹음... 하는 순간...

입력 순서를 원하는대로 받으려면,


끌 올도 못하는데 새로고침 무지 하면서 올리기 버튼 눌러야 합니다.

(맨 위로 올림도 없고 그냥 무식하게 계속 올려야 합니다)

아니 이미 존재하는 모듈상에 코드가 존재하잖아요, 끌어 올리기...

모듈로 따로 개발하고 코딩한 이유가 그런 거 섞어쓰기 편하려던 목적 같은데...

객체지향... 내가 메뉴에서 마우스로 끌어 올리고 내리고 하는 코드 몰라도 그렇게 되게끔...


더 열받는 것은 잘못 누르면 다시 내려가요 ㅠㅠ


게다가 여러가지 테스트를 해보면 전화번호나 기타 값을 해보면 html 코드에 보면 id=extra_var3-1055

이런 식으로 각 기본값들에 대해서 엄청난 숫자 번호까지 매기는데, 이 값도 전혀 쓸모 없습니다.

순차적으로 이것도 그냥 인덱스죠.


그러니 무식한 코딩을 쓴 후에는 변수값 하나 추가하는 순간 멘붕인거죠.


그래서 앞에 과정을 해둔 것입니다.


위의 코드를 수정해보면,


<input type="text" name="extra_vars1" placeholder="{$extra_keys_map['testInput']->name}" style="width:155px;" value="{$extra_keys_map['testInput']->value}" class="text" />


이렇게 바꿔주는 거죠.



이제 우리가 활용하게 되는 것은,

extra_vars숫자 (사용자 정의 에서 나오는 앞의 숫자값입니다) 와 사용자 변수명이 되었습니다.


간단히 설명드리겠습니다.

placeholder 값은 당연히 입력 칸에 살짝 흐리게,

비 로그인 상태에서 글쓰기 할 때에, 비밀번호 -> 이렇게 써서 입력 받잖아요? 그런 태그 속성입니다.

사용자 정의 이름 입력할 때에 Ex) extra_vars_1 이라는 것도 마찬가지로 구현되어 있죠.

실제로는 밑줄 없습니다. 밑줄빼기도 아니고... 이건 뭐;;;


아무튼,


{$extra_keys_map['testInput']->name} 이게 사용자 변수의 입력항목 이름이 되는 거죠.


그리고 이 부분이 중요합니다.


style="width:155px;"


이게 입력 칸의 너비 조절이 되는 거죠.

size 로는 안됩니다. 원래 형식이 들어 있는 Extravar.class.php 에서 고친다고 해도 저렇게 고쳐줘야 작동합니다.


이제 이렇게 해준 상태에서,


가장 중요한 부분이죠.

이것 때문에 이 긴 글을 읽고 있는데 말입니다;



value="{$extra_keys_map['testInput']->value}"


이렇게 해주면 값 전달이 되어서 수정시에도 제대로 되겠죠.


그리고 지금은 맵을 두가지로 쓰기 때문에 루프 돌 때에도 사용자 변수명으로 if 써서 foreach 등에 끼어들기가 쉽습니다.

변수명 자체를 활용할 수 있으니까요.


오늘은 여기까지 설명하구요,


다음에는 사용자 정의 변수 형식에 우리 입맛대로 쑤셔 넣는 방법을 배우겠습니다.


그걸 해줘야, 시간이든, 해외 국제 전화번호든...

우리 넣고 싶은 값을 다 넣을 수 있죠.


코딩같은 코딩은 이번만 조금 다루고, 다음부터는 일단 무조건 노가다입니다.

2019년 달력, 사진엽서(소량) 판매합니다(+이벤트)

https://blog.naver.com/bob_ss/22139614603

     원문 : https://blog.naver.com/bob_ss/22139614603
<div class="se_background_dim"></div>

2019년 캘린더와 엽서.
2018년 '버킷리스트(
[재능을 통한]기부)'를 위한 '위시리스트'로, 달력과 엽서(2차)를 제작 했습니다. 
순 수익금의 29%는 후원할 예정입니다.
(제작 배경 : 
https://blog.naver.com/bob_ss/221396142038)

얼마 전 여행다니며 찍은 사진들 중, 맘에 드는 사진 몇 장을 선별해서 
엽서를 만들어 무료나눔을 했었는데 생각보다 반응이 좋아 
너무 감사하게 2차 제작을 하게 되었습니다.
(1차 나눔 : 
https://blog.naver.com/bob_ss/221395123936)


처음 해보는 분야(?)에 미적 감각이 없던 터라, 약 2~3주 동안 고생아닌 고생을 했습니다. 

제작 중에 동생도 그 뜻을 같이 해보고싶다 하여 도움을 주었습니다. 


공대생 의 디자인 치곤 몇몇 검토자(?)분들 께서 만족해 하셔서
샘플 제작하고 검수까지 완료했고, 최종 인쇄 요청을 했습니다. 

 

사진은 여행지에서 밥남매(저와 동생)이 '지금 이 순간'을 기억하고 싶어 노력해서 찍은 사진들이고, 
저만의 느낌을 조금 더 담은
(보정) 열정(?)이 들어갔습니다. 

좋은 사진들이 많아 어려웠지만, 
달력은 13장의 사진(표지포함)엽서는 14장의 사진을 선정해 제작합니다. 

 
달력, 엽서
1. 달력세트

달력세트 입니다.

 

달력은 2가지 세트가 있어요.  월별 사진은 밑쪽에 있습니다. 
인테리어에 감성을 더해줄      
① 일본감성세트
유럽의 모던함을 느낄 수 있는 
② 유럽세트

 
 
달력세트 기본구성
 

구매하신 분들을 위해 끈과 집게 그리고 받침대까지 예쁘게 포장해서 보내드려요.

2019 달력구성

사이즈 : A5(21.0x14.8cm)  * A5 사이즈로, 벽걸이 형 대형달력이 아닙니다!
재   질 : 르느와르 230g (두껍고 도톰한 종이로 잘 구겨지지 않습니다)
구   성 : 달력내지 12p, 표지 1p
             엽서 1장
(이벤트, 한정수량, 랜덤), 포장,
             액세서리 3종(원목받침대
[한정], [약 90cm내외], 나무집게 3개)
                   * 원목받침대는 핸드메이드 제품으로, 특성 상 옹이/갈라짐 등 있을 수 있습니다. 
                   * 7장까지 달력을 꽂을 수 있습니다. 
가   격 : 10,900원
(배송비 별도)
배송비 : 3,000원(제주, 산간 별도요금)

달력 월별 구성
 
일본감성세트(좌), 유럽모던세트(우)
2. 엽서세트

엽서세트입니다

 
 


엽서도 
2가지 세트가 있어요.   
① A.너의이름은 ② B.안녕,오늘
추천받아서 지은 이름입니다(오글거려도 참아주..)

 

기본 세트는 이렇게 7장씩 구성돼 있고, 추가로 선택하여 구매하실 수 있습니다.

 

엽서도 정성스레 포장해서 보내드려요! 
(사탕은 불포함..^^;)

엽서 구성

사이즈 : 규격엽서(14.8x10.0cm)
재   질 : 르느와르 230g (두껍고 도톰한 종이로 잘 구겨지지 않습니다)
구   성 : 엽서 내지 7장, 포장, [약 90cm내외]
가   격 : 5,900원
(배송비 별도)
배송비 : 3,000원(제주, 산간 별도요금)
* 달력과 같이 구매하시면 1,000원 할인 합니다. 

구매 방법

<안내사항>
- 소량 주문 제작이기 때문에 현재 재고 소진(?.. 희망사항) 시에는 추가 제작 후 발송 예정입니다. (11.16.금 추가주문)
- 엽서 기본 세트는 수량을 맞춰 제작했기에 구성품 일부를 다른 상품으로 교환이 어렵습니다. 
- 달력은 낱장으로 구성되어있습니다.
- 달력은 A5 사이즈로, 벽에 거는 대형 사이즈가 아니니 구매 시 참고해 주세요!
- 25,000원 이상 구매 시 배송비는 무료입니다. 
1. 아래의 정보를 비밀 댓글로 달아주세요 

① 상품명 
② 수량
③ 성함 
④ 연락처  
⑤ 주소 
2. 댓글 확인 후 구매 가능여부와 가격 / 입금계좌 안내해드리겠습니다.
3. 입금 확인 후 안내 댓글 드린 후, 최대한 빠르게 꼼꼼하게 포장해서 배송 드리겠습니다

댓글은 여기(https://blog.naver.com/bob_ss/22139614603)에서 달아주세요





1. Integers(Int) / 정수타입 


let age = 25



2. Floating Point Number / 실수


Float은 소숫점 6자리까지

Double은 소숫점 15자리 

애플은 굳이 Float이 필요하지 않으면 Double을 권유함



3. Boolean /  참 거짓 확인을 위한 타입


let isTrue = true //Bool
Binary 값으로, Swift는 0/1로 인식함.
(True = 1, False = 0)


'공부 > iOS' 카테고리의 다른 글

Swift Naming Convention  (0) 2018.11.08
Swift 변수 Variables / 상수 let 차이  (0) 2018.11.08
iOS ) UIImage VS CGImage VS CIImage  (0) 2018.11.03


1. Concatenation


let address = "Seoul" + ", " + "Yongsan" + ", " + "Hangangro"
print(address)
 -> "Seoul, Yongsan, Hangangro"


2. String Interpolation


let city = "Seoul
let country = "South Korea" 

let interpolatedAddress = "\(city)"
print(interpolatedAddress)
 -> "Seoul"

interpolatedAddress = "\(city), \(country)"
print(interpolatedAddress)
 -> "Seoul, South Korea


Swift 시 통상 사용하는 규칙들

 


1. 띄어쓰기 허용X


let programminglanguage = "Objective-c"

2. 낙타표기법 사용


let favoriteProgrammingLanguage = "Swift"



3. 숫자로 시작할 수 없다


4. 스페이스, 탭과 같은 공백문자도 허용 X


5. 수학기호 사용 X

'공부 > iOS' 카테고리의 다른 글

Swift Numbers& Booleans 정수, 실수  (0) 2018.11.08
Swift 변수 Variables / 상수 let 차이  (0) 2018.11.08
iOS ) UIImage VS CGImage VS CIImage  (0) 2018.11.03

변수(Mutable Type)

var str = "hello, playGround"


str = "Hello, World"


변수 선언 


var number = 7

 = > 가능



상수(Immutable Type)

let language = "Swift"


language = "Objective-c" 

 -> Cannot assign to value : "laungage' is a 'let' constant

에러

'공부 > iOS' 카테고리의 다른 글

Swift Numbers& Booleans 정수, 실수  (0) 2018.11.08
Swift Naming Convention  (0) 2018.11.08
iOS ) UIImage VS CGImage VS CIImage  (0) 2018.11.03

UIImage VS CGImage VS CIImage



● UIImage 

UIImage라는 이름에 걸맞게, UIImage는 UIKit안에 있는 클래스입니다.

정의도 간단;;;


"An object that manages image data in your app."

"앱의 이미지 데이터를 관리하는 객체입니다."


이미지 객체를 사용하여 모든 종류의 이미지 데이터를 표현 할 수 있으며, UIImage 클래스는 기본 플랫폼에서 지원하는 모든 이미지 형식의 데이터를 관리 할 수 있습니다. 
이미지객체는 변경 불가능(immutable)하므로, 당신은 항상 이미 존재하는 디스크에있는 이미지파일이나 프로그래밍으로 생성된 이미지 데이터에서 새로운 이미지객체를 만들어야 합니다.
이미지 객체가 모든 플랫폼 고유의 이미지 형식을 지원하지만 앱의 대부분의 이미지에 PNG 또는 JPEG 파일을 사용하는 것이 좋습니다. 객체는 두 형식 모두를 읽고 표시 할 수 있도록 최적화되어 있으며 이러한 형식은 다른 대부분의 이미지 형식보다 우수한 성능을 제공합니다. PNG 형식은 무손실이기 때문에 앱 인터페이스에서 사용하는 이미지에 특히 좋습니다.




● CGImage 

<CGColor와 UIColor의 차이>글을 읽고오신분이라면...CG라는 것을 보고......바로 알아챘을 수도 ㅎㅎ..
네, CGImage의 CG는 Core Graphics의 약자입니다!!!
Core Graphics 프레임워크 안에 있는 녀석이죠.
정의는;;UIImage보다 더 간단함 

"A bitmap image or image mask."
"비트맵 이미지 또는 이미지 마스크."

허허..이걸 알려면 Quartz 2D Programming Guide를 읽어야 하네요..
간단하게 말하면, CGImage는 비트맵만 나타낼 수 있다고 합니다. blend modes나 masking과 같은 작업에는 CGImageRefs가 필요해요. 
실제 비트 맵 데이터에 접근하고 변경해야하는 경우 CGImage를 사용할 수 있습니다. 또한 NSBitmapImageReps로 변환 될 수 있습니다. CGImage에서 새로운 UIImage를 생성하려면, 이런식으로 하면 돼요. 

var aNewUIImage = UIImage(CGImage: imageRef)
//where imageRef is a CGImage




CGImage의 프로퍼티들을 보면, 



아주 비트비트스럽죠





 CIImage 

CIImage의 CI는 뭘까...

못들어본 사람도 있을거에요! 바로 "Core Image"라는 프레임워크의 약자이며, CIImage는 바로 이 Core Image프레임워크 안에 있는 클래스에요.

정의는 

"A representation of an image to be processed or produced by Core Image filters."

"코어 이미지 필터(Core Image filters)에 의해 처리되거나 생성 될 이미지의 표현."

그리고 아주아주 흥미로운 정보가 있어요.


"A CIImage is a immutable object that represents an image. It is not an image."

CIImage는 이미지를 나타내는 불변(immutable)객체 입니다. 그것(CIImage)은 이미지가 아닙니다. 


이미지가 아니래요!!! 이미지가 아니면 뭐냐? 

"관련된 이미지 데이터만 있으며, 이미지를 생성하는데 필요한 모든 정보가 있습니다"

오...신기..더 알아봅시다.


일반적으로 CIImage 객체는 CIFilter, CIContext, CIColor 및 CIVector와 같은 다른 Core Image 클래스와 함께 사용됩니다. CIImage 객체에는 연관된 이미지 데이터가 있지만 이미지가 아닙니다. CIImage 객체를 이미지 "레시피(recipe)"로 생각할 수 있습니다.


CIImage 객체는 이미지를 생성하는 데 필요한 모든 정보를 가지고 있지만 Core Image  실제로 그렇게 할 때까지(실제로 이미지를 생성할 때 까지) 이미지를 렌더링하지 않습니다. 

이 "게으른 평가(lazy evaluation)"방법은 Core Image가 가능한 한 효율적으로 작동하도록합니다.


CIContext 및 CIImage 객체는 변경 불가능합니다. 즉, 각 객체를 스레드간에 안전하게 공유 할 수 있습니다. 여러 스레드가 동일한 GPU 또는 CPU CIContext 객체를 사용하여 CIImage 객체를 렌더링 할 수 있습니다. 


하지만 이는 CIFilter객체 경우에는 아닙니다. CIFilter 객체는 스레드간에 안전하게 공유 할 수 없습니다

앱이 다중 스레드 인 경우 각 스레드는 고유 한 CIFilter 객체를 만들어야합니다. 


Core Image는 자동 조정 방법도 제공합니다. 이 메소드는 이미지에 공통적 인 결함이 있는지 분석하고 해당 결함을 수정하기 위해 일련의 필터를 반환합니다. 필터에는 스킨 톤, 채도, 대비 및 그림자의 값을 변경하고 플래시로 인한 적목 현상 또는 기타 아티팩트를 제거하여 이미지 품질을 향상시키는 값이 미리 설정되어 있습니다. 


OverView에 있는 내용을 번역해본건데..막 스레드니.......뭐니...잘 이해가 안가죠? 그래서 CIImage로 뭘 할 수 있는데;;

CIImage를 가지고, CIFilter등 다른 Core Image 클래스를 사용하면,

이런거


또는 이런거





를 할 수 있게됩니다. 그냥 쉽게 생각해서!!!!!이미지에 필터 씌울 수 있다!!!!라고 생각하시면 편합니다. 아니 음..Core Image에서의 기능 중 하나라고 보시면 됩니다. 이런 작업들을 하려면 CIImage로 해야한다는 것이죠.

CIFilter를 보면..정말 엄청나게 많은 효과?필터?들을 이미지에 입힐 수 있다는 것을 보실 수 있습니다...


음...솔직히 말해서 CGImage는 아직 조금 감이 안온달까

비트맵을 다룰 수 있다는건 알겠는데....어떤식으로 뭘 할 수 있는지...잘...ㅎㅎ..

오늘 글을 정리하자면, 앱 내에서 기본 이미지 타입을 다룰거라면 UIImage(png가 제일 좋다), 비트맵을 다룰거라면 CGImage, 이미지에 필터나 다양한 효과를 적용하고 싶다면 CIImage를 사용하면 된다?..이정도가 되겠네요 :)

오늘도 도움이 되었길 바래요 :) 혹시 틀린부분이 있다면 댓글로 말해주세요 XD


참고 : https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94

https://developer.apple.com/library/content/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIBoxBlur

https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html

https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html



출처: https://zeddios.tistory.com/455 [ZeddiOS]

'공부 > iOS' 카테고리의 다른 글

Swift Numbers& Booleans 정수, 실수  (0) 2018.11.08
Swift Naming Convention  (0) 2018.11.08
Swift 변수 Variables / 상수 let 차이  (0) 2018.11.08

https://m.blog.naver.com/metooneis/221205368477


+ Recent posts