[CodeIgniter] _rmap을 이용한 화면 상단, 하단 레이어 고정[CodeIgniter] _rmap을 이용한 화면 상단, 하단 레이어 고정

Posted at 2020. 2. 12. 17:31 | Posted in PHP/CodeIgniter
반응형




■ 코드이그나이터에서 헤더 푸터 레이아웃 지정





코드이그나이터의 함수요청 리다이렉트를 통해


웹 페이지 상단(헤더), 하단(푸터)를 고정적으로 노출 시키려고 한다.


기본적으로 코드이그나이터를 세팅하면 보게되는


Welcome to CodeIgniter! 페이지에


헤더와 푸터를 나타내 보자




# 컨트롤럴 소스코드

 /codeIgniter/application/controllers/Welcome.php

<?php

defined('BASEPATH') OR exit('No direct script access allowed');


class Welcome extends CI_Controller {


/**

@brief 기본 Wellcome to CodeIgniter! 페이지 지정

*/

public function index() {

$this->load->view("welcome_message");

}


/**

* @brief 사이트 헤더, 푸터가 자동으로 추가

*/

public function _remap($method) {


// brief 헤더 load

$this->load->view("layer/headder_view");


if(method_exists($this, $method)) {

$this->{"{$method}"}();

}


// @brief 푸터 load

$this->load->view("layer/footer_view");

}

}




# 헤더 레이아웃

 /codeIgniter/application/views/layer/headder_view.php

<header style="background-color:#333333;padding-top:30px;padding-left:20px;padding-bottom:20px;">

    <a href="http://magic.wickedmiso.com/" style="color:#FFFFFF;text-decoration:none;">

        <span style="font-size:20px;font-weight:bold;color:#C52D2F;">사악미소</span>의 현대마법의 공방

    </a>

</header>




# 푸터 레이아웃

 /codeIgniter/application/views/layer/footer_view.php

<footer style="background-color:#333333;padding-top:15px;padding-left:40px;padding-bottom:15px;color:#FFFFFF;">

    Created by saakmiso

</footer>





# 출력결과








반응형
//

[Kotlin] 코틀린이란?[Kotlin] 코틀린이란?

Posted at 2020. 2. 12. 13:13 | Posted in Kotlin
반응형




발췌 : Do it! 코틀린 프로그래밍





■ 코틀린의 탄생 배경



-. 코틀린( Kotlin )은 IntelliJ IDEA라는 통합 개발 환경으로 유명한 젯브레인즈( JetBrains )에서 개발했다.


-. 구글의 안드로이드 스튜디오또한 IntelliJ IDEA 기반이며 코틀린을 공식 언어로 지원하고 있다.


-. 코틀린은 프로그래밍이 가능한 멀티플랫폼 언어이다.


 Kotlin / JVM

 · 자바 가상 머신에서 동작하는 애플리케이션을 제작

 Kotlin / JS

 · 자바스크립트로 웹 브라우저에서 동작하는 애플리케이션을 만들 수 있다.

 Kotlin / Native

 · LLVM 컴파일러를 이용하여 여러 플랫폼을 타깃으로 하는 애플리케이션을 만들 수 있다.


-. 코틀린은 JVM, JS, Native 상에서 실행될 수 있다.


 ① JVM( Java Virtual Machine, 자바 가상 머신) 기반의 코틀린은 자바 애플리케이션이나 안드로이드 애플리케이션을 만들 수 있다.


 ② JS( Java Script )  기반의 코틀린은 데이터베이스부터 서버, 클라이언트까지 다루는 풀스택( Full-Stack ) 웹 개발이 가능하다.


 ③ Native 기반의 코들린은 LLVM 컴파일러를 통해 다양한 플랫폼을 타깃으로 한 기계의 코드를 만들 수 있다.


 · 안드로이드 환경( arm32, arm64 )

 · 윈도우 환경( MinGW x86_64 )

 · 애플 iOS 환경( arm32, arm64, emulator x86_64)

 · 애플 맥 OS 환경( x86_64 ) 

 · 리눅스 환경( x86_64, arm32, MIPS, MIPS little-endian)

 · 웹 전용 환경( wasm32 )


    쉡게 말해 코드를 한번만 작성해도 Android와 iOS에서 모두 구동하는 애플리케이션을 만들 수 있다.


    또는 임베디드, IoT( Internet of Things )등을 타깃으로 한 애플리케이션을 만들 수 있다.








■ 코틀린의 장점




#01. 자바와의 완벽한 호완


코틀린은 자바와 완벽하게 호환되므로 자바 코드를 바꾸지 않고도 자바와 혼용하여 사용할 수 있다.


간단히 마라면 다양한 환경에서 사용할 수 있다.




#02. 자료형 오류를 미리 잡을 수 있는 정적 언어


코틀린은 프로그램이 컴파일될 때 자료형을 검사하여 확정하는 정적 언어이다.


즉 자료형 오류를 초기에 발견할 수 있어 프로그램의 안전성이 뛰어나다.




#03. 널 포인터( Null Pointer ) 예외로 인한 프로그램 중단을 예방할 수 있다.


컴퓨터 프로그래밍에 경험이 있다면, 널 포인터 예외( Null Pointer Exception )를 한번쯤은 경험하게 된다.


널 포인터 예외는 프로그램이 실행되는 도중에 발생하기 때문에 언제 어디서 어떻게 발생할지 아무도 알 수 없지만,


코틀린의 경우 널 포인터 예외를 사전에 예방할 수 있어 좋다.




#04. 간결하고 효율적


코틀린은 여러 가지 생략된 표현이 가능한 어어이다.


그래서 다른 언어보다 훨씬 간결하고 효율적으로 코딩이 가능하다.




#05. 함수형 프로그래밍과 객체 지향 프로그래밍이 모두 가능하다.


함수를 변수에 저장하거나 함수를 다른 함수의 매개변수로 넘길 수 있는 함수형 프로그래밍과,


클래스를 사용하는 객체 지향 프로그래밍을 둘다 할 수 있다.




#06. 세미콜론을 생략할 수 있다.


코드를 작성할 때 줄 마지막에 사용하던 세미콜론( ; )을 생략할 수도 있다.









■ 안드로이드 공식 언어로 채택된 코틀린




#01. 자바와 안드로이드 그리고 코틀린


자바 언어는 제임스 고슬링( James Gosling )이 만들었고 초기에는 썬 마이크로 시스템즈( Sun Microsystems )에서 관리해 왔다.


하지만 곧 썬 마이크로 시스템즈가 오라클에 인수되고 제임스 고슬링이 회사를 떠나면서


오라클이 자바 JDK( Java Development Kit )의 개발과 관리를 전적으로 주도하고 있다.



자바는 전 세계적으로 가장 널리 사용되고 있으며 언어 자체는 무료이지만,


오라클이 썬 마이크로 시스템즈를 인수한 다음 특정 자바 JDK에 대해 유료화 정책을 시작하였다.



이런 상황에서 구글은 자바 JDK를 통해 안드로이드 핵심 프레임워크와 여러 서비스를 이미 개발한 생태였기에,


오라클은 구글에게 몇 가지 자바 JDK를 사용한 API( Application Programming Interface )에 대하여


천문학적인 금앨의 특허 사용료를 요구했고 구글이 이를 거부하면서 구글과 오라클은 긴 시간동안 법정 소송을 벌여왔기에


몇가지 이해관계를 살펴볼 필요가 있다.




#02. 자바 언어와 Oracle JDK


자바 언어 자체는 무료로 사용할 수 있다.


다만 자바 언어로 프로그램을 작성하기 위해서는 SDK( Software Development Kit ) 자바 JDK가 필요하며,


자바 바이트코드를 실행하기 위해서는 JVM이 필요하다.



오라클은 Oralcle JDK와 JVM의 특정 기능을 사용할 때 라이선스 비용을 지불하는 정책을 시행하고 있기에,


구글은 이러한 분쟁을 피하기 위해 자체적인 가상 머신( DalvikVM 및 ART )을 만들거나


새로운 SDK를 제작하는 등의 조치를 취해 왔고,


자바언어를 대체하려고 코틀린을 안드로이드 공석 언어로 채택하게 되었다.


다만 하위 호환성을 고려하면 안드로이드의 모든 자바 프레임워크를 코틀린으로 다시 작성하기가 어렵기 때문에


안드로이드에서는 자바와 코틀린을 혼용해야 한다.




#03.  OpenJDK


오라클은 썬 마이크로 시스템즈를 인수하면서 기존의 썬 마이크로 시스템즈가 오픈소스화했던 JDK( Open JDK )를 유지한 상태로


Oracle JDK를 지속적으로 발전시키고 있다.



OpenJDK에는 오라클이 제공하는 몇 가지 사용 기능이 빠져 있으나 라이선스 비용을 지불하지 않는 GPLv2 라이선스를 따르는


오픈소스이기 떄문에 누구든 자유롭게 소스를 이용하고 배포할 수 있다.



라이선스 지불 비용과 관련한 대책으로 아줄 시스템즈( Azul Systems )에서 OpenJDK에 부가 기능을 넣어


TCK 인증을 통과시킨 Zulu라는 JDK가 존재한다.



 Oracle JDK 공식 웹 사이트

 · https://www.oracle.com/technetwork/java/javase/

 Open JDK 공식 웹 사이트

 · https://openjdk.java.net/

 Zulu 공식 웹 사이트

 · https://www.azul.com/downloads/zulu/










■ 코틀린으로 개발한 안드로이드 애플리케이션들



 · 핀터레스트( Pinterest)

 · 에버노트 ( Evernote )

 · 트렐로( Trello )

 · 스퀘어( Square )

 · 코세라( Coursera )

 



아직은 자바로 만든 안드로이드 애플리 케이션이 많지만,


구글이 2017 Google I / O에서 코틀린을 안드로이드 공식 언어로 발표한 이후 코틀린으로 만든 안드로이드 어플리케이션이 점점 더 많아지고 있다.


그만큼 코틀린이 개발자에게 인정받는 효율적인 언어라는 반증이 될 것이다.









반응형
//

[PHP] PHPExcel 시트 추가하기[PHP] PHPExcel 시트 추가하기

Posted at 2020. 2. 11. 20:06 | Posted in PHP/PHP Library
반응형




■ PHPExcel 시트 나누고 데이터 삽입하기



# 소스코드

<?php

include "./classes/PHPExcel.php";

$objPHPExcel = new PHPExcel();


$rocketPunch = array(


    // 첫번째 시트에 사용될 데이터 값

    "pinkPunch" => array(

          "1" => "PINK PUNCH"

        , "2" => "BIM BAM BUM"

        , "3" => "Love Is Over"

        , "4" => "Lucid Dream"

        , "5" => "Favorite"

        , "6" => "Do Something"

    )


    // 두번째 시트에 사용될 데이터 값

    , "redPunch" => array(

          "1" => "RED PUNCH"

        , "2" => "BOUNCY"

        , "3" => "So Solo"

        , "4" => "Fireworks"

        , "5" => "Paper Star"

        , "6" => "Lilac"

        , "7" => "Girl Friend"

    )

);


// @breif Worksheet 라는 이름으로 생성되는 기본 시트를 삭제한다.

$objPHPExcel -> removeSheetByIndex(0);


// @breif 생성할 시트의 순번

$sheetNum = 0;


foreach($rocketPunch as $title => $album) {


    // @breif createSheet( ) 함수로 새로운 시트를 생성한다.

    $objWorkSheet = $objPHPExcel -> createSheet($sheetNum);


    // @breif 엑셀 시트 이름 지정

    $objWorkSheet -> setTitle($title);


    // @breif 타이틀 영역 지정

    $objWorkSheet -> setCellValue("A1", "NO.");

    $objWorkSheet -> setCellValue("B1", "Song");


    // @breif 엑셀에 데이터 삽입

    $row = 1;

    foreach($album as $key => $val) {

        $row++;

        $objWorkSheet -> setCellValue(sprintf("A%s", $row), $key);

        $objWorkSheet -> setCellValue(sprintf("B%s", $row), $val);

    }


    // @breif 각 행의 간격

    $objWorkSheet -> getColumnDimension("A") -> setWidth(10);

    $objWorkSheet -> getColumnDimension("B") -> setWidth(30);


    // @breif 각 로우의 디자인

    $objWorkSheet -> getStyle(sprintf("A1:B%s", $row)) -> getAlignment() ->

    setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);

    $objWorkSheet -> getStyle(sprintf("A1:B%s", $row)) -> getBorders() -> getAllBorders() ->

    setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

    $objWorkSheet -> getStyle("A1:B1") -> getFont() -> setBold(true);

    $objWorkSheet -> getStyle("A1:B1") -> getFill() -> setFillType(PHPExcel_Style_Fill::FILL_SOLID) ->

    getStartColor() -> setRGB("CECBCA");

    $objWorkSheet -> getStyle(sprintf("A2:B%s", $row)) -> getFill() -> setFillType(PHPExcel_Style_Fill::FILL_SOLID) ->

    getStartColor() -> setRGB("F4F4F4");


    // @breif 숫자앞에 기본적으로 0을 붙일 수 있게 한다.

    $objWorkSheet -> getStyle(sprintf("A2:A%s", $row)) -> getNumberFormat() -> setFormatCode("00");


    $sheetNum++;

}


// @breif 문서를 오픈할 시 첫번째 시트로 열리게 설정

$objPHPExcel -> setActiveSheetIndex(0);


// @breif 파일의 저장형식이 utf-8일 경우 한글파일 이름은 깨지므로 euc-kr로 변환해준다.

$filename = iconv("UTF-8", "EUC-KR", "울림_로켓펀치");


header("Content-Type:application/vnd.ms-excel");

header("Content-Disposition: attachment;filename=".$filename.".xls");

header("Cache-Control:max-age=0");


$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel5");

$objWriter -> save("php://output");

?>




# 출력결과









반응형
//

[jQuery] JCROP을 이용한 이미지 자르기 - Sample[jQuery] JCROP을 이용한 이미지 자르기 - Sample

Posted at 2020. 2. 11. 13:29 | Posted in JavaScript & jQuery/jQuery
반응형

 

 

 

 

Jcrop 다운 : http://deepliquid.com/content/Jcrop.html

Jcrop API : https://jcrop.com/

GitHub : https://github.com/tapmodo/Jcrop

 

 

 

 

■ JCROP을 이용한 업로드한 크롭( CROP ) 하기

 

 

 

 

웹 브라우저 상에서 이미지를 업로드하고, 해당 이미지를 편집 하는 기능을 제작하게 되었다.

 

HTML5의 캔버스를 통해 업로드한 이미지를 똑같이 복사하여, 작업영역을 만들고.

 

캔버스에서 작업이 완료된 그림을 다시 원본 이미지와 교체하는형태로 서버에 업로드 하지 않고 작업하는것을 마무리 하였다.

 

 

 

# 소스코드

<html>
<head>
<meta charset="UTF-8">
<title>:: JavaScript 캔버스 이미지 업로드 ::</title>
<meta name="viewport" content="width=device-width">
<link type="text/css" rel="stylesheet" href="./css/modern.css"/>
<link type="text/css" rel="stylesheet" href="http://jcrop-cdn.tapmodo.com/v0.9.12/css/jquery.Jcrop.min.css"/>
<style type="text/css">
    .imgArea { text-align:center; }
    canvas, #uploadFile, #editBtn, #cutBtn { display:none; }
    body { overflow:hidden };
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="http://jcrop-cdn.tapmodo.com/v0.9.12/js/jquery.Jcrop.min.js"></script>
<script type="text/javascript">


    let jcropApi = null;


    // @breif 이미지 크롭 영역지정 UI 나타내기
    function imgCropDesignate() {


        let editWidth = jQuery("#editImg").width();
        let editHeight = jQuery("#editImg").height();
       
        // @breif jcrop 실행시 크롭영역을 미리 세팅
        let x1 = window.screen.width / 2 - editWidth;
        let y1 = window.screen.height / 2 - editHeight;
        let x2 = editWidth / 1.5;
        let y2 = editHeight / 1.5;


        // @breif jcrop 실행
        jQuery("#editImg").Jcrop({
              bgFade : true
            , bgOpacity : .2
            , setSelect : [ x1, y1, x2, y2 ]
            , onSelect : updateCoords
        }, function() {
            jcropApi = this;
        });
        
        jQuery("#editBtn").css("display", "none");
        jQuery("#cutBtn").css("display", "inline");
    }
    
    // @breif 지정된 크롭 한 영역( 좌표, 넓이, 높이 )의 값을 보관하는 함수
    function updateCoords(crap) {
        jQuery("#xAxis").val(crap.x);
        jQuery("#yAxis").val(crap.y);
        jQuery("#wLength").val(crap.w);
        jQuery("#hLength").val(crap.h);
    }


    // @breif 크롭한 영역 잘라내고 추출하기
    function imgCropApply() {


        if(parseInt(jQuery("#wLength").val()) == "NaN") {
            alert("이미지를 크롭한 이후\n자르기 버튼을 클릭하세요.");
            return false;
        } else {


            let editImage = new Image();
            editImage.src = jQuery("#editImg").attr("src");


            editImage.onload = function() {


                // @breif 캔버스 위에 이미지 그리기
                let canvas = document.querySelector("canvas");
                let canvasContext = canvas.getContext("2d");


                // @breif 캔버스 크기를 이미지 크기와 동일하게 지정
                canvas.width = jQuery("#wLength").val();
                canvas.height = jQuery("#hLength").val();
                                
                canvasContext.drawImage(
                      this
                    , jQuery("#xAxis").val()        // 자르기를 시작할 x좌표
                    , jQuery("#yAxis").val()        // 자르기를 시작할 y좌표
                    , jQuery("#wLength").val()    // 잘라낸 이미지의 넓이
                    , jQuery("#hLength").val()    // 잘라낸 이미지의 높이
                    , 0                                         // 캔버스에 이미지를 배치할 x좌표
                    , 0                                         // 캔버스에 이미지를 배치할 y좌표
                    , jQuery("#wLength").val()    // 사용할 이미지의 넓이(이미지 스트레칭 또는 축소)
                    , jQuery("#hLength").val()    // 사용할 이미지의 높이(이미지 스트레칭 또는 축소)
                );


                // @breif 편집한 캔버스의 이미지를 화면에 출력한다.
                let dataURI = canvas.toDataURL("image/jpeg");
                jQuery("#editImg").attr("src", dataURI);
                
                // @breif 이미지의 크기는 자른 이미지와 동일하게 지정
                jQuery("#editImg").css("width", jQuery("#wLength").val());
                jQuery("#editImg").css("height", jQuery("#hLength").val());
            };


            jQuery("#cutBtn").css("display", "none");


            // @details JCROP을 종료한다.
            jcropApi.destroy();
    jcropApi = null;
        }
    }


    // @breif 이미지 업로드 함수
    function uploadImgFilePrinted() {


        // @details 업로드 파일 정보를 받아온다.
        let fileInfo = document.getElementById("uploadFile").files[0];
        let reader = new FileReader();


        reader.onload = function() {


            // @details 업로드 이미지 출력
            jQuery("#editImg").attr("src", reader.result);
            
            // @details 이미지 크기를 제목 영영과 같게 출력
            jQuery("#editImg").css("width", jQuery("h1").width());
            
            // @details 이미지 업로드 기능 제거, 추가 업로드 방지
            jQuery("#editImg").parent("a").removeAttr("onClick");
            
            // @details 편집버튼 노출
            jQuery("#editBtn").css("display", "inline");
            
            canvasDrawImage(function() {
            alert("이미지 업로드가 완료되었습니다.");
            });
        };


        if(fileInfo) {     
            // @details readAsDataURL을 통해 업로드한 파일의 URL을 읽어 들인다.
            reader.readAsDataURL(fileInfo);
        }
    }


    // @breif 캔버스 이미지 생성
    function canvasDrawImage(callback) {


        let prepImage = new Image();
        prepImage.src = jQuery("#editImg").attr("src");


        prepImage.onload = function() {


            // @details 캔버스 위에 이미지 그리기
            // jQuery("canvas") 와같은 명령은 사용할 수 없다.
            let canvas = document.querySelector("canvas");
            let canvasContext = canvas.getContext("2d");


            canvas.width = jQuery("#editImg").width();
            canvas.height = jQuery("#editImg").height();
            canvasContext.drawImage(this, 0, 0, jQuery("#editImg").width(), jQuery("#editImg").height());


            // @details 캔버스의 이미지
            let dataURI = canvas.toDataURL("image/jpeg");
            jQuery("#editImg").attr("src", dataURI);
            
            callback();
        };
    }
</script>
</head>
<body>
<input type="hidden" id="xAxis" value="0" placeholder="선택영여역의_x좌표"/>
<input type="hidden" id="yAxis" value="0" placeholder="선택영여역의_y좌표"/>
<input type="hidden" id="wLength" value="0" placeholder="선택영여역의_w넓이"/>
<input type="hidden" id="hLength" value="0" placeholder="선택영여역의_h높이"/>
<input type="file" id="uploadFile" onChange="uploadImgFilePrinted();" accept="image/*"/>
<div class="contents">
    <h1>이미지&nbsp;자르기<span>샘플</span></h1>
    <div class="imgArea">
        <a href="javascript:;" onClick="jQuery('#uploadFile').click();">
            <img id="editImg" src="./user-anonymous.png"/>
        </a>
        <br/><br/>
        <input id="editBtn" type="button" onClick="imgCropDesignate();" value="편집"/>
        <input id="cutBtn" type="button" onClick="imgCropApply();" value="자르기"/>
    </div>
    <canvas></canvas>
    <div class="copyright" style="bottom:0;">
        <p>Producer &copy; 사악미소</p>
    </div>
</div>
</body>
</html> 

 

 

 

 

# 출력결과

 

 

 

 

관련포스팅#01 : [JavaScript] 이미지 파일 썸네일 생성하기

관련포스팅#02 : [JavaScript] Canvas를 통한 이미지 회전

관련포스팅#03 : [JavaScript] Canvas로 이미지 서버에 전송하기 - Sample

관련포스팅#04 : [jQuery] JCROP을 이용한 이미지 자르기 - Sample

 

 

 

 

 

반응형
//