Tag Archive image

Byphunsanit

docker: image tag version

การสร้าง docker container วิธีต่างๆ จะเห็นคำว่า tag อยู่ในทุกคำสั่ง เช่น

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

ที่เวลาใช้จะพิมย์ เป็น

docker pull php:7.1.10-fpm

ตอนแรกผมเข้าใจว่ามันคือ keyword ไว้อธิบายว่า container ตัวนี้มันคืออะไร ทำมาจากอะไร แต่จริงๆแล้ว มันไม่ใช่ keyword ที่ไว้ค้นหา แต่ก็ไม่ได้ผิดไปนัก

การอ้างถึง image จะประกอบด้วย 2 ส่วนคือ image:version

image
image คือต้นแบบโปรแกรมที่เราใช้ เหมือนไฟล์ .iso ที่เป็นไฟล์ที่จำลองแผ่น cd / dvd ตอนเราติดตั้งโปรแกรม เราไม่ได้ใช้ไฟล์ .iso ทำงานต่างๆให้เรา image ก็เช่นกันไว้ติดตั้ง apache, mysql แต่ไม่ได้ทำงานแทนโปรแกรมพวกนั้นเป็นแค่ ต้นฉบับไว้ให้จำลองเป็น container
tag หรือ version
เป็นตัวบอกว่า ให้ติดตั้ง image version ที่เท่าไหร่ เช่น php 5.6.31 ถ้าไม่ระบุเวอร์ชั่น docker จะเลือกตัวล่าสุดหรือ :latest ให้โดยอัตโนมัติ

เราสามารถค้นหา image ได้จาก Docker Hub

บาง image จะมีหลาย repository ให้เลือกใช้ (แนวคิดเดียวกับ distro ของ linux เลย)

  • ตัวที่เป็นทางการหรือ official repository หรือ library จะมี link แบบ https://hub.docker.com/_/php/ ใช้โดยเขียน php หรือ php: ตามด้วย tag (version) ได้เลย
  • ส่วนตัวอื่นจะมี ชื่อผู้ผลิตนำหน้า เช่น https://hub.docker.com/r/appsvc/php/ เวลาใช้ก็ต้องอ้าง appsvc/php: ตามด้วย tag (version)

บาง image ยังมีหลาย version ให้เลือกอีก เช่น 7.1.10-alpine, 7.1.10-apache, 7.1.10-cli, 7.1.10-fpm ให้เลือกอีก

ถ้าเราไม่ใส่ :tag จะหมายถึง tag :latest หรือ ใหม่ที่สุดเท่าที่จะมีใน image ตัวนั้นๆ

Byphunsanit

PHPExcel: จัดรูปแบบ format ข้อมูล

เมื่อวานเขียน export ข้อมูลออกเป็นไฟล์ excel โดยใช้เวลาไม่นาน เพราะโครงสร้างการทำงานมันเหมือนๆ งานที่เคยทำมา แต่มาตกม้าตายเอาที่การฟอร์เมตของแต่ละ column ให้ตรงกับชนิดข้อมูล เช่น type เป็น date ก็ควรให้เห็นเป็นวันที่ไม่ใช่เลข 1234155 อะไรก็ไม่ทราบ

<?php

include '../vendor/phpoffice/phpexcel/Classes/PHPExcel.php';

set_time_limit(0);

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

$defaultStyle->getNumberFormat()
    ->setFormatCode('yyyy-mm-dd');

/* Set document properties */
$title = 'columnsType_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('CMS')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* create new sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

$columns = [
    'row_number' => ['title' => 'No.', 'type' => 'row_number'],

    'price' => ['title' => 'ราคา', 'type' => 'currency'],

    'dateEnd' => ['title' => 'เริ่มจำหน่าย', 'type' => 'date'],
    'dateStart' => ['title' => 'เริ่มจำหน่าย', 'type' => 'date'],

    'dateApproved' => ['title' => 'เวลาอนุมัติ', 'type' => 'datetime'],

    'height' => ['title' => 'สูง (เมตร)', 'type' => 'float'],
    'width' => ['title' => 'กว้าง (เมตร)', 'type' => 'float'],

    'calculate' => ['title' => 'สูตรคํานวณหวย', 'type' => 'formula'],

    'image' => ['title' => 'ภาพ', 'type' => 'image'],

    'items' => ['title' => 'จำนวน', 'type' => 'integer'],

    'productName' => ['title' => 'ชื่อสินค้า', 'type' => 'string'],

    'timeEnd' => ['title' => 'เวลาขาย', 'type' => 'time'],
    'timeStart' => ['title' => 'เวลาปิดการขาย', 'type' => 'time'],

    'url' => ['title' => 'page', 'type' => 'url'],
];

/* header */
$colNo = -1;
$rowNo = 1;
$colStrings = [];
foreach ($columns as $fieldId => $field) {
    $colNo++;
    $colStrings[$colNo] = $colString = PHPExcel_Cell::stringFromColumnIndex($colNo);
    $objWorkSheet->setCellValue($colString . '1', $field['title']);
    $objWorkSheet->setCellValue($colString . '2', 'type = ' . $field['type']);
}
$headerHeight = $rowNo = 2;

$objPHPExcel->getActiveSheet()->freezePane($colString . ($headerHeight + 1));

/* random data */
$datas = [];
for ($a = 0; $a < 10; $a++) {
    $temp = [];

    $temp['calculate'] = '=RAND()';
    $temp['dateApproved'] = date(DATE_ISO8601, mt_rand(0, 1499291999));
    $temp['dateEnd'] = date('Y-m-d', mt_rand(0, 1499291999));
    $temp['dateStart'] = date('Y-m-d', mt_rand(0, 1499291999));
    $temp['height'] = mt_rand(0, 10) / 10;
    $temp['image'] = 'http://lorempixel.com/400/200/sports/?st=' . mt_rand(1, 500);
    $temp['items'] = mt_rand(999, 9999999);
    $temp['price'] = mt_rand(100, 10000);
    $temp['productName'] = substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil(10 / strlen($x)))), 1, 10);
    $temp['timeEnd'] = date('H:i:s', mt_rand(0, 1499291999));
    $temp['timeStart'] = date('H:i:s', mt_rand(0, 1499291999));
    $temp['url'] = 'https://plusmagi.com/?s=' . mt_rand(1, 500);
    $temp['width'] = mt_rand(0, 10) / 10;

    array_push($datas, $temp);
}

/* add data */
$row_number = 0;
foreach ($datas as $item) {
    $colNo = -1;
    $row_number++;
    $rowNo++;
    foreach ($columns as $fieldId => $field) {
        $colNo++;

        $coordinate = $colStrings[$colNo] . $rowNo;

        switch ($field['type']) {
            case 'date':
            case 'datetime':
            case 'time':{
                    $ts = strtotime($item[$fieldId]);
                    $value = PHPExcel_Shared_Date::PHPToExcel($ts);
                }break;

            case 'image':{
                    $value = $item[$fieldId];

                    $gdImage = imagecreatefromjpeg($value);
                    $objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); /*create object for Worksheet drawing*/

                    $objDrawing->setCoordinates($coordinate); /*set image to cell*/
                    $objDrawing->setDescription('Customer Signature'); /*set description to image*/
                    $objDrawing->setHeight(50);
                    $objDrawing->setImageResource($gdImage);
                    $objDrawing->setName('Customer Signature'); /*set name to image*/
                    $objDrawing->setOffsetX(25); /*setOffsetX works properly*/
                    $objDrawing->setOffsetY(10); /*setOffsetY works properly*/
                    $objDrawing->setWidth(100); /*set width, height*/

                    $objDrawing->setWorksheet($objWorkSheet); /*save*/

                    $objWorkSheet->getRowDimension($rowNo)->setRowHeight(60); /* set row height*/
                }break;

            case 'row_number':{
                    $value = $row_number;
                }break;

            case 'url':{
                    $value = str_replace('http://', '', $item[$fieldId]);
                    $objWorkSheet->getCell($coordinate)
                        ->getHyperlink()
                        ->setTooltip('Click here to access page')
                        ->setUrl($item[$fieldId]);
                }break;

            default:{
                    $value = $item[$fieldId];
                }break;
        }

        $objWorkSheet->setCellValue($coordinate, $value);
    }
}

/* auto width column */
$cellIterator = $objWorkSheet->getRowIterator()->current()->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true);
foreach ($cellIterator as $cell) {
    $objWorkSheet->getColumnDimension($cell->getColumn())->setAutoSize(true);
}

/* format for columns */
$colNo = -1;
foreach ($columns as $fieldId => $field) {
    $colNo++;

    $coordinate = $colStrings[$colNo] . ($headerHeight + 1) . ':' . $colStrings[$colNo] . $rowNo;

    switch ($field['type']) {

        case 'currency':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode('#,##0.00');
                /*->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER);*/
            }break;

        case 'date':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH);
            }break;

        case 'datetime':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);
                /*->setFormatCode('Y-m-d H:i:s');*/
            }break;

        case 'float':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
            }break;

        case 'integer':
        case 'row_number':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode('#,##');
            }break;

        case 'time':{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
                /*->setFormatCode('Y-m-d H:i:s');*/
            }break;

        default:{
                $objWorkSheet->getStyle($coordinate)
                    ->getNumberFormat()
                    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
            }break;
    }

}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');

หลักการต้องทำงานคู่กัน 2 ส่วนคือ

  1. ส่วนใส่ข้อมูล บางชนิดต้องแปลงข้อมูลก่อน เช่น date, datetime, timestamp และ time ต้องเปลี่ยนเป็น unix timestamp ก่อน
  2. ส่วนกำหนด cell format (ในตัวอย่างให้วิธีกำหนดทั้ง column ไปเลย) ต้องเลือกรูปแบบที่เหมาะสมโดยจะกำหนดเอง
    ->setFormatCode('Y-m-d H:i:s');

    หรือจะใช้ตามมาตราฐานก้ได้ Class PHPExcel_Style_NumberFormat ก็ได้

Byphunsanit

PHPExcel: ใส่ภาพในไฟล์

บางครั้งการ export ข้อมูลออกไปเป็นไฟล์ excel ก็ต้องการใส่ภาพลงไปด้วย อาจจะเป็นโลโก้บริษัท หรือว่าเป็นภาพตัวอย่างสินค้า PHPExcel สามารถแทรกภาพได้ทั้งจาก file หรือ url ของภาพที่ออนไลน์อยู่

<?php

include 'vendor/phpoffice/phpexcel/Classes/PHPExcel.php';

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
    ->setName('Arial')
    ->setSize(11);

/* Set document properties */
$title = 'Exports_Datas_' . date('Y-m-d_H:i');
$objPHPExcel->getProperties()->setCreator('Pitt Phunsanit')
    ->setCategory('Exports Datas')
    ->setDescription($title)
    ->setKeywords('Exports Datas ' . date('Y-m-d'))
    ->setSubject($title)
    ->setTitle($title);

/* rename sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle('Exports Datas');

/* image path */
$images = [
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/officelogo.jpg',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/paid.png',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/phpexcel_logo.gif',
    'https://raw.githubusercontent.com/PHPOffice/PHPExcel/1.8/Examples/images/termsconditions.jpg',
    'vendor/phpoffice/phpexcel/Examples/images/officelogo.jpg',
    'vendor/phpoffice/phpexcel/Examples/images/paid.png',
    'vendor/phpoffice/phpexcel/Examples/images/phpexcel_logo.gif',
    'vendor/phpoffice/phpexcel/Examples/images/termsconditions.jpg',
];

$rowNo = 0;
foreach ($images as $image) {
    $rowNo++;

    $coordinate = 'A' . $rowNo;

    $objWorkSheet->getRowDimension($rowNo)->setRowHeight(90);
    $objWorkSheet->setCellValue($coordinate, $image);

    switch (strtolower(pathinfo($image, PATHINFO_EXTENSION))) {
        case 'gif':
            $gdImage = imagecreatefromgif($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF;
            break;

        case 'jpeg':
        case 'jpg':
            $gdImage = imagecreatefromjpeg($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG;
            break;

        case 'png':
            $gdImage = imagecreatefrompng($image);
            $mimetype = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG;
            $render = PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG;
            break;
    }

    $objDrawing = new PHPExcel_Worksheet_MemoryDrawing();

    $objDrawing->setCoordinates($coordinate);
    $objDrawing->setImageResource($gdImage);
    $objDrawing->setWorksheet($objWorkSheet);

    /* optional */
    $objDrawing->setDescription($image);
    $objDrawing->setMimeType($mimetype);
    $objDrawing->setName(pathinfo($image, PATHINFO_FILENAME));
    $objDrawing->setRenderingFunction($render);
    $objDrawing->setResizeProportional(true);
    $objDrawing->setWidth(100);

}

$objWorkSheet->getColumnDimension('A')->setAutoSize(true);

/* write */
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $title . '.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$objWriter->save('php://output');

อธิบาย

setCoordinates
ตำแหน่งที่ให้ภาพไปลอยอยู่
setDescription
รายละเอียด (optional)
setName
ชื่อภาพ (optional)
setResizeProportional
รักษาสัดส่วนของภาพเอาไว้
setWorksheet
อ้างถึง Active Sheet หรือ sheet ที่ใส่ข้อมูล
ถ้าเลือกใช้ PHPExcel_IOFactory::createWriter ผิด version เช่น ‘Excel5’ อาจจะทำให้ภาพมีสัดส่วนเพี้ยนได้
Byphunsanit

พรีวิวรูปที่อัพโหลด

ถ้าเวลาเรา upload รูปขึ้น server คงจะดีถ้าเราเห็นว่าเราเลือกภาพถูกรึเปล่า หรือขนาดมันใหญ่เกินไปมั๋ย เราทำได้โดยการแสดงภาพ Preview ขนาด ความกว้าง ความสูง และทำการตรวจสอบก่อนจะได้ไม่เสียเวลา

ตัวอย่าง jQuery Upload Image Preview Demo

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Upload Image Preview</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
	<label>เฉพาะรูปภาพ
		<input type="file" name="pic" accept="image/*">
	</label>
</form>
<img id="picPreview">
<dl>
	<dt>image dimensions width</dt>
	<dd id="picDimensionsWidth"></dd>
	<dt>image dimensions height</dt>
	<dd id="picDimensionsHeight"></dd>
	<dt>lastModified</dt>
	<dd id="picLastModified"></dd>
	<dt>lastModifiedDate</dt>
	<dd id="picLastModifiedDate"></dd>
	<dt>name</dt>
	<dd id="picName"></dd>
	<dt>original file upload path</dt>
	<dd id="picPath"></dd>
	<dt>size</dt>
	<dd id="picSize"></dd>
	<dt>type</dt>
	<dd id="picType"></dd>
</dl>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$('[name="pic"]').change(function(){

	/* original file upload path */
	$('#picPath').text($(this).val());

	var file = this.files[0];
	/* get picture details */
	$('#picLastModified').text(file.lastModified);
	$('#picLastModifiedDate').text(file.lastModifiedDate);
	$('#picName').text(file.name);
	$('#picSize').text(file.size);
	$('#picType').text(file.type);

	/* set image preview */
	if( ! file.type.match(/image.*/))
	{
		return true;
	}
	var reader = new FileReader();
	reader.onload = function (event)
	{
		$('#picPreview').attr('src', event.target.result);

		/* get image dimensions */
		var image = new Image();
		image.src = reader.result;
		image.onload = function()
		{
			$('#picDimensionsWidth').text(image.width);
			$('#picDimensionsHeight').text(image.height);
		};

	}
	reader.readAsDataURL(file);

});
</script>
</body>
</html>
Byphunsanit

เลือกชนิดไฟล์อัพโหลด

คุณสมบัติที่น่าสนใจอย่างหนึ่งของ HTML 5 คือเราสามารถกำหนดให้อินพุทยอมรับชนิดไฟล์ตามที่เราต้องการได้ ช่องใส่ภาพประจำตัว ก็น่าจะใส่ได้แค่นามสกุล jpeg อย่างน้อยก็ png หรือ gif แต่ก็มียูเซอร์ copy รูปใส่ word upload เข้ามา สมกับ used เซ่อๆ จริงๆ
เราสามารถกำหนดได้โดยใช้ accept Attribute ตามตัวอย่าง

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5 Form Input Accept</title>
<style>
label
{
	display: block;
}
</style>
</head>
<body>
<form action="" enctype="multipart/form-data">
	<label>เฉพาะไฟล์เสียง
		<input type="file" name="files[]" accept="audio/*">
	</label>
	<label>เฉพาะรูปภาพ
		<input type="file" name="files[]" accept="image/*">
	</label>
	<label>เฉพาะวีดีโอ
		<input type="file" name="files[]" accept="video/*">
	</label>
	<label>pdf
		<input type="file" name="files[]" accept="application/pdf">
	</label>
	<label>.gif หรือ .png
		<input type="file" name="files[]" accept="image/gif, image/png">
	</label>
	<label>.jpg
		<input type="file" name="files[]" accept="image/pjpeg, image/jpeg">
	</label>
	<input type="submit">
</form>
</body>
</html>

จะสังเกตุว่าเวลาเรา browse file มันจะแสดงเฉพาะนามสกุลที่เรากำหนด แต่ยังเปลี่ยนตัวเลือกไปเป็น All Files (*.*) ได้อยู่ดี มันแค่ช่วยให้เลือกไฟล์ได้ง่ายขึ้น ยังรับประกันไม่ได้อยู่ดีว่าจะได้นามสกุลไฟล์ที่ถูกต้อง หรือไฟล์ที่ส่งมานามสกุลถูกตาม Extension แต่ก็ไม่ได้รับรองว่าไฟล์มันเป็นจริงตามนามสกุลที่ส่งมา จุดที่อันตรายก็เลยต้องมาตรวจชนิดไฟล์ในผั่ง server อยู่เหมือนเดิม

ค่าที่ใส่ใน accept คือ MIME Types ดูเพิ่มเติมได้ที่ The Complete List of MIME Types

Byphunsanit

ค้นหาจากภาพ

ต้องการที่จะหาภาพถ่ายของใครซักคนในเครื่อง แต่เก็บไว้หลายที่เหลือเกิน แทนที่จะเปิดดูที่ละภาพลองใช้ picasa (เจ้าของคือ google) โหลดได้ที่ http://picasa.google.com/ หลังจากลงแล้วโปรแกรมจะหาภาพ และหาภาพคนที่คล้ายกันมาให้ใส่ tag ใช้แล้วอาจจะลืม acdsee หรือโปรแกรมดูภาพอื่นๆ ไปเลย ดีและฟรีจริงๆครับ

ถ้าเอารูปเก่าๆ ออกมาดู แต่จำไม่ได้ว่าเคยถ่ายไว้ที่ไหน ลองลากรูปไปวางในช่องค้นหาของ google ก็จะได้ข้อมูลสถานที่ออกมา (เร็วจนตกใจ) อ่านดูรายละเอียดวิธีใช้ได้ที่ ค้นจากภาพ

ส่วนใครที่ออกแบบเว็บ ไปเห็นตัวอักษรสวยๆ แต่ไม่รู้ว่าเป็นชุดอักษรอะไร เข้าไปใช้บริการ What The Font ไม่กี่คลิก ก็ได้รายชื่อพร้อมตัวอย่างฟอนต์มาให้เลือก

ดูเพิ่มเติม