【Gulp】GulpでPNGとJPEGを圧縮する

以前、鹿野さんが書いた下記の記事をベースに作ったものをPNG,JPEGの両方に対応するように作り直してみたメモ。

5分で導入! タスクランナーGulpでWeb制作を効率化しよう – ICS MEDIA

全体的な解説は鹿野さんの記事に詳しいので、ここでは変更点のみ記します。

・PNGの圧縮は、imagemin-pngquan を使う方がいいらしいので、こっちを追加。以下のコマンドで該当フォルダにインストール。

npm install --save-dev imagemin-pngquan

・JPEGの圧縮は、imagemin-mozjpeg を使うため追加。以下のコマンドで該当フォルダにインストール。

npm install --save-dev imagemin-mozjpeg

※ちなみに「–save-dev」はinstallしたlibraryの情報を自動でpackage.jsonに書いてくれるオプションです。
npmでnode.jsのpackageを管理する – Qiita

・複数の拡張子を指定するには、{} で囲めばいいらしい(gulpfile.js 11行目)。

・PNG,JPEG共に圧縮設定を追加(gulpfile.js 12-25行目)。

これらを書き足したコードが以下です。

・gulpfile.js(全文)

// gulpプラグインの読みこみ
var gulp = require('gulp');

// 画像を圧縮するプラグインの読み込み
var imagemin = require("gulp-imagemin");
var pngquant  = require('imagemin-pngquant');
var mozjpeg  = require('imagemin-mozjpeg');

// imagesフォルダのpng,jpg画像を圧縮して、minified_imageフォルダに保存する
gulp.task("imageMinTask", function() {  // 「imageMinTask」という名前のタスクを登録
    gulp.src("images/*.{png,jpg}")    // imagesフォルダ以下のpng,jpg画像を取得
    .pipe(imagemin([
       pngquant({
         quality: '65-80',
         speed: 1,
         floyd:0
       }),
       mozjpeg({
         quality:85,
         progressive: true
       }),
       imagemin.svgo(),
       imagemin.optipng(),
       imagemin.gifsicle()
     ]
        ))   // 画像の圧縮処理
        .pipe(gulp.dest("minified_image/"));    //保存
});

実際に圧縮してみた結果は、こんな感じでした。

・PNG
(圧縮前)2534 × 3490 ピクセル 2.9 MB(2,854,228 バイト)
(圧縮後)2534 × 3490 ピクセル 1.6 MB(1,555,755 バイト)> 約55%に圧縮

・JPEG
(圧縮前)3024 × 4032 ピクセル 6.3 MB(6,335,114 バイト)
(圧縮後)3024 × 4032 ピクセル 1 MB(1,032,033 バイト)> 約16%に圧縮

【参考】
Gulpでpngquantを使ってPNGの減色&軽量化 – Qiita
gulp-imageminのプラグインによる最適化が機能しない際の対処 – Qiita

【node.js】node.js,npm,bower,gulpなどの諸々

最近この辺使うので、とりあえず個人的なリンクのまとめ。

・node.js,npm関連
npm自体のバージョンを上げる – Qiita
nodebrewでnodeとnpmのバージョン管理しよう(Mac編) | Webサプリ
Macにnode.jsを複数バージョン切り替えられるようにインストール – Qiita
nodebrewでnodeとnpmのバージョン管理しよう(Mac編) | Webサプリ
nodebrewで手軽にnode.jsバージョンアップ&バージョン切り替え – Qiita
Cordovaの環境構築 – Qiita

・bower関連
Bower(フロントエンド用パッケージマネージャー)の導入方法と使い方 | 株式会社LIG

・Gulp関連
5分で導入! タスクランナーGulpでWeb制作を効率化しよう – ICS MEDIA
ざっくりGulp.js入門(Mac向け) – Qiita
Gulpでpngquantを使ってPNGの減色&軽量化 – Qiita
gulp-imageminのプラグインによる最適化が機能しない際の対処 – Qiita

・ターミナル関連
Mac OS X ターミナルで別のボリュームへ移動するには?? – Qiita
必ず使える!Macのターミナルで使う基本UNIXコマンド15選 | NEZU.log

今更ながらPHPでFacebook API でログイン処理を書いてみた(v2.8)

【MacOS X 10.11.6 + Facebook API v2.8 + Facebook SDK for PHP v5.0】
必要があってFacebookのログイン処理をPHPで書いてみたので、そのメモです。

1.Facebookに開発者登録してサイトをアプリとして登録

Facebook APIを使うには、Facebookに開発者登録してサイトをアプリとして登録する必要があります。その辺はここでは割愛するので、ご存じない方は下記を参照のこと。
Facebook開発者登録の方法とアプリ作成方法の手順

※この辺の説明はたくさんありますが、サイトによってはキャプチャ画面が古いものもあるので、適宜読み替えが必要。

2.Facebook SDK for PHP v5.0 のインストール

以下から、手動インストール。
facebook for developers | スタートガイド – ウェブSDK
解凍後、サイトのルートに「php-graph-sdk-5.0.0/src/Facebook」をフォルダごとコピーする。

3.PHPでのログイン処理

下記のサイトを参考にしました。コールバックのURLもパス付きで書いてあって、わかりやすいです。
[Facebook SDK for PHP v5.0]を利用してログイン認証をおこなう[Oauth]

ざっと図解すると、こんな感じ。

FacebookAPIの画面遷移

以下、各phpの概要です。

・config.php

Facebook APIで使用する、アプリID,app secret,APIのバージョンを定義。実際にAPIを使用するphpに、require_onceで読み込ませるために共通化。各設定項目とダッシュボードとの対応は、以下の通り。

app_id:アプリID
app_secret:app secret
default_graph_version:APIバージョン

アプリのダッシュボード画面

・index.php

Facebook APIでアプリにログインさせる。実際にはAPI側で、Facebookのログイン及びアプリの認証の可否を確認する画面が表示されるため、ユーザーの意に反してログインされることはない。

・callback.php

Facebook APIからのコールバックを受け取るphp。ここでアクセストークンを取得し、ログインしたユーザー情報を取得する。ユーザーがログインしない/アプリを許可しない場合、取得できないのでindex.phpへのリンクを表示。取得できた場合は、member.phpへ。

・member.php

ログインしたユーザー情報を表示する。

・logout.php

アプリからログアウトする。クッキーを削除して、セッションを破棄することでログアウトになる。

4.コールバックURLをアプリの管理画面に登録

コールバックURLはアプリの管理画面に登録する。左メニューから「プロダクト」>「+製品を登録」>「Facebookログイン」選ぶ。「クライアントOAuth設定」の「有効なOAuthリダイレクトURI」にコールバックURLをフルパスで指定し、右下の「変更を保存」ボタンを押す。

Facebookログインの画面でコールバックURLを指定して、保存する。

4.アクセストークン取得にはコールバックURLの指定が必要

参考サイトのコードをそのまま使ったら、「URLを読み込めません: このURLのドメインはアプリのドメインに含まれていません。このURLを読み込むには、アプリ設定のアプリドメインにすべてのドメインとサブドメインを追加してください。」というエラーが出た。

以下のサイトを参考に、アクセストークン取得のところにコールバックのURIを指定してエラーを解消。

【PHP】 Facebook APIのOauthのエラー解決「URLを読み込めません」「Can’t Load URL」 | codechord

実際にはこんな感じに書き換える。

//アクセストークンを取得する
$accessToken = $helper->getAccessToken('https://c-geru.sakura.ne.jp/c-geru/fb_test/callback.php');

5.デモ

実際の動作デモは、こちらからどうぞ。

6.各ソース

上記4.で述べたように、アクセストークン取得(callback.php)とログイン(index.php)の2箇所でコールバックURLが必要になるため、このサンプルでは、config.phpにコールバックURLを定義して、各phpではセッションから値を取得するようにしました。

・config.php

<?php 
session_start(); 
require_once("Facebook/autoload.php"); 
//コールバックURLをセッションに保存 
$_SESSION['fb_callback_ulr'] = 'https://c-geru.sakura.ne.jp/c-geru/fb_test/callback.php'; 
$fb = new Facebook\Facebook([
  'app_id' => '○○○○○○○○○',
  'app_secret' => '△△△△△△△△△△△△△',
  'default_graph_version' => 'v2.8',
]);

・index.php

<?php 

session_start(); 
header("Content-type: text/html; charset=utf-8"); 

//設定ファイルを読み込み 
require_once("config.php"); 

//コールバックURLの取得 
$callcak_url = $_SESSION['fb_callback_ulr']; 
$helper = $fb->getRedirectLoginHelper();

//オプションによって認証画面の文言が変わる
//$permissions = ['email', 'user_likes','user_posts']; //あなたの公開プロフィール、メールアドレス、タイムライン投稿、いいね!。
//$permissions = ['email', 'user_likes']; //あなたの公開プロフィール、メールアドレス、いいね!。
//$permissions = ['email', 'user_posts'];//あなたのタイムライン投稿。
//$permissions = ['email','user_friends'];//あなたの公開プロフィール、友達リスト、メールアドレス。
//$permissions = ['email'];//あなたの公開プロフィール、メールアドレス。
$permissions = [];//あなたの公開プロフィール。
$loginUrl = $helper->getLoginUrl($callcak_url, $permissions);

echo '<a href="' . $loginUrl . '">ログインする</a>';

・callback.php

<?php 

session_start(); 

header("Content-type: text/html; charset=utf-8"); 

//設定ファイル 
require_once("config.php"); 

//コールバックURLの取得 
$callcak_url = $_SESSION['fb_callback_ulr']; 

//タイムゾーンの設定 
date_default_timezone_set('asia/tokyo'); 

$helper = $fb->getRedirectLoginHelper();

try {
	if (isset($_SESSION['facebook_access_token'])) {
		$accessToken = $_SESSION['facebook_access_token'];
	} else {
		//アクセストークンを取得する
		$accessToken = $helper->getAccessToken($callcak_url);
	}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
	// When Graph returns an error
	echo 'Graph returned an error: ' . $e->getMessage();
	exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
	// When validation fails or other local issues
	echo 'Facebook SDK returned an error: ' . $e->getMessage();
	exit;
}

if (isset($accessToken)) {
	//アクセストークンをセッションに保存
	$_SESSION['facebook_access_token'] = (string) $accessToken;
	
	header('Location: member.php');
	exit();
}else{
	echo "<a href='index.php'>はじめのページへ</a>";
}

・member.php

<?php 

session_start(); 
header("Content-type: text/html; charset=utf-8"); 
//設定ファイル 
require_once("config.php"); 

if (isset($_SESSION['facebook_access_token'])) { 
$accessToken = $_SESSION['facebook_access_token']; 
$fb->setDefaultAccessToken($accessToken);
	
	try {
		//取得するユーザ情報の指定
		$response = $fb->get('/me?fields=id,name,first_name,last_name,email,gender');
		$profile = $response->getGraphUser();
		
		//ユーザ画像取得
		$UserPicture = $fb->get('/me/picture?redirect=false&height=200');
		$picture = $UserPicture->getGraphUser();
		
	} catch(Facebook\Exceptions\FacebookResponseException $e) {
		// When Graph returns an error
		echo 'Graph returned an error: ' . $e->getMessage();
		exit;
	} catch(Facebook\Exceptions\FacebookSDKException $e) {
		// When validation fails or other local issues
		echo 'Facebook SDK returned an error: ' . $e->getMessage();
		exit;
	}
	
	$id=$profile['id'];
	$name=$profile['name'];
	$first_name=(isset($profile['first_name'])) ? $profile['first_name'] : '';
	$last_name=(isset($profile['last_name'])) ? $profile['last_name'] : '';
	$email=$profile['email'];
	$gender=(isset($profile['gender'])) ? $profile['gender'] : '';
	$picture_url = $picture['url'];
    
   
	echo "アクセストークン:".$accessToken."";
	echo "ID:".$id."";
	echo "名前:".$name."";
	echo "性別:".$gender."";
	echo "ファーストネーム:".$first_name."";
	echo "ラストネーム:".$last_name."";
	echo "メール:".$email."";//ユーザが未公開・未設定の場合は表示されない
	echo "<img src=".$picture_url.">";
	echo "<a href='logout.php'>ログアウト</a>";

}else{
	header('Location: index.php');
	exit();
}
?>

<!--#_=_を排除する-->
<script type="text/javascript">
if (window.location.hash && window.location.hash == '#_=_') {
  if (window.history && history.pushState) {
      window.history.pushState("", document.title, window.location.pathname);
  } else {
    // Prevent scrolling by storing the page's current scroll offset
    var scroll = {
        top: document.body.scrollTop,
      left: document.body.scrollLeft
    };
    window.location.hash = '';
    // Restore the scroll offset, should be flicker free
    document.body.scrollTop = scroll.top;
    document.body.scrollLeft = scroll.left;
  }
}
</script>

・logout.php

<?php
session_start();
 
header("Content-type: text/html; charset=utf-8");

//セッション変数を全て解除
$_SESSION = array();
 
//セッションクッキーの削除
if (isset($_COOKIE["PHPSESSID"])) {
    setcookie("PHPSESSID", '', time() - 1800, '/');
}
 
//セッションを破棄する
session_destroy();
 
echo "ログアウトしました。"; 
echo "<a href='index.php'>はじめのページへ</a>";