2014年9月7日日曜日

jpgのロスレス圧縮を行う

前回のpngのロスレス圧縮を行うからの続きで、
今度はjpgの圧縮を行いたいと思います。

jpgの圧縮にはjpegoptimを使えば良いそうなので、
こちらを試したいと思います+(0゚・∀・) + ワクテカ +

まずはインストールを行います。
yum install jpegoptim
Loaded plugins: aliases, changelog, downloadonly, fastestmirror, kabi, presto, priorities, security, tmprepo, verify, versionlock
Loading support for CentOS kernel ABI
You need to be root to perform this command.
$ sudo yum install jpegoptim
Loaded plugins: aliases, changelog, downloadonly, fastestmirror, kabi, presto, priorities, security, tmprepo, verify, versionlock
Loading support for CentOS kernel ABI
Loading mirror speeds from cached hostfile
epel/metalink                                                                                                                                               | 4.0 kB     00:00
 * base: ftp.iij.ad.jp
 * centosplus: ftp.iij.ad.jp
 * elrepo: ftp.ne.jp
 * epel: ftp.jaist.ac.jp
 * extras: ftp.iij.ad.jp
 * rpmforge: mirror.fairway.ne.jp
 * updates: ftp.iij.ad.jp
base                                                                                                                                                        | 3.7 kB     00:00
centosplus                                                                                                                                                  | 3.4 kB     00:00
elrepo                                                                                                                                                      | 2.9 kB     00:00
epel                                                                                                                                                        | 4.4 kB     00:00
epel/primary_db                                                                                                                                             | 6.3 MB     00:01
extras                                                                                                                                                      | 3.3 kB     00:00
rpmforge                                                                                                                                                    | 1.9 kB     00:00
Not using downloaded repomd.xml because it is older than what we have:
  Current   : Fri Jul 11 10:46:59 2014
  Downloaded: Wed Jul 25 10:43:04 2012
updates                                                                                                                                                     | 3.4 kB     00:00
195 packages excluded due to repository priority protections
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package jpegoptim.x86_64 0:1.4.1-1.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===================================================================================================================================================================================
 Package                                     Arch                                     Version                                         Repository                              Size
===================================================================================================================================================================================
Installing:
 jpegoptim                                   x86_64                                   1.4.1-1.el6                                     epel                                    26 k

Transaction Summary
===================================================================================================================================================================================
Install       1 Package(s)

Total download size: 26 k
Installed size: 52 k
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 26 k
jpegoptim-1.4.1-1.el6.x86_64.rpm                                                                                                                            |  26 kB     00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : jpegoptim-1.4.1-1.el6.x86_64                                                                                                                                    1/1
  Verifying  : jpegoptim-1.4.1-1.el6.x86_64                                                                                                                                    1/1

Installed:
  jpegoptim.x86_64 0:1.4.1-1.el6

Complete!
バージョンの確認
jpegoptim -V
jpegoptim v1.4.1  x86_64-redhat-linux-gnu
Copyright (c) 1996-2014  Timo Kokkonen.

libjpeg version: 6b  27-Mar-1998
Copyright (C) 1991-2010 Thomas G. Lane, Guido Vollbeding
Copyright (C) 1999-2006 MIYASAKA Masaru
Copyright (C) 2009 Pierre Ossman for Cendio AB
Copyright (C) 2009-2012 D. R. Commander
Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)
ヘルプの確認
jpegoptim -h
jpegoptim v1.4.1  Copyright (c) Timo Kokkonen, 1996-2014.
Usage: jpegoptim [options] 

  -d, --dest=
                    specify alternative destination directory for
                    optimized files (default is to overwrite originals)
  -f, --force       force optimization
  -h, --help        display this help and exit
  -m, --max=
                    set maximum image quality factor (disables lossless
                    optimization mode, which is by default on)
                    Valid quality values: 0 - 100
  -n, --noaction    don't really optimize files, just print results
  -S, --size=
                    Try to optimize file to given size (disables lossless
                    optimization mode). Target size is specified either in
                    kilo bytes (1 - n) or as percentage (1% - 99%)
  -T, --threshold=
                    keep old file if the gain is below a threshold (%)
  -b, --csv         print progress info in CSV format
  -o, --overwrite   overwrite target file even if it exists
  -p, --preserve    preserve file timestamps
  -q, --quiet       quiet mode
  -t, --totals      print totals after processing all files
  -v, --verbose     enable verbose mode (positively chatty)
  -V, --version     print program version

  -s, --strip-all   strip all markers from output file
  --strip-none      do not strip any markers
  --strip-com       strip Comment markers from output file
  --strip-exif      strip Exif markers from output file
  --strip-iptc      strip IPTC/Photoshop (APP13) markers from output file
  --strip-icc       strip ICC profile markers from output file
  --strip-xmp       strip XMP markers markers from output file

  --all-normal      force all output files to be non-progressive
  --all-progressive force all output files to be progressive
  --stdout          send output to standard output (instead of a file)
  --stdin           read input from standard input (instead of a file)
簡単な使い方は次のような感じです

画像に含まれるExif情報などを全て削除する
--strip-allを付けて実行します。
jpegoptim --strip-all ファイル名
個別に削除したい場合は次のようにします。

・コメントのみ
jpegoptim --strip-com ファイル名
・Exifのみ
jpegoptim --strip-exif ファイル名
・IPTCのみ
jpegoptim --strip-iptc ファイル名
・ICCプロファイルのみ
jpegoptim --strip-icc ファイル名
・XMPのみ
jpegoptim --strip-xmp ファイル名
データを削除しない場合は--strip-noneを付ける。
jpegoptim --strip-none ファイル名
品質を指定して圧縮

品質(クオリティ)を指定して画像を圧縮します。
<quality>には0から100の値を入れる。100が最大圧縮率になる。
jpegoptim -m ファイル名
サイズを指定して圧縮

画像をKB単位で指定して、そのサイズまで圧縮。
指定したサイズによって画質が劣化する。
数字の後に%を付けることで圧縮率を指定することもできるそうです。
jpegoptim -Sサイズ ファイル名
保存ディレクトリを指定
保存場所を指定することで上書きを防ぐことができます。
jpegoptim --dest=ディレクトリパス ファイル名
処理結果を出力しない
jpegoptim -q ファイル名
同名ファイルが存在しても上書き
jpegoptim -o ファイル名

圧縮率を100%で指定したディレクトリへ圧縮ファイルを出力する場合
jpegoptim -m100 --dest=/tmp/test/ /tmp/test.jpg
/tmp/test.jpg 190x60 24bit N Exiff XMP Adobe  [OK] 22571 --> 16274 bytes (27.90%), optimized.
27.90%圧縮されました( ´∀`)bグッ!

圧縮率を100%で、Exif情報などを削除して指定したディレクトリへ圧縮ファイルを出力する場合
jpegoptim --strip-all -m100 --dest=/tmp/test/ /tmp/test.jpg
/tmp/test.jpg 190x60 24bit N Exiff XMP Adobe  [OK] 22571 --> 15369 bytes (31.91%), optimized.
同じファイルで31.91%圧縮されましたъ(゚Д゚)グッジョブ!!

指定されたディレクトリ配下に含まれるjpg,jpeg画像を圧縮する。
また、圧縮したファイルを指定したディレクトリに出力する
find /tmp/ -name "*.jpg" -o -name "*.jpeg" | xargs jpegoptim --strip-all -m100 --dest=/tmp/test/ {}
以上です(`・ω・´)ゞビシッ!!

参考URL

2014年9月6日土曜日

pngのロスレス圧縮を行う

Google先生のPageSpeed Insightsに引き続き、次のようにお怒りを頂いています(´;ω;`)ブワッ

画像を適切にフォーマット化して圧縮すると、
データ サイズを大きく削減できます。ロスレス圧縮してください( ‘д‘⊂彡☆))Д´) パーン

とのことでした(´;ω;`)ウッ…

ロスレス圧縮とは? lossless圧縮
lossless圧縮とは、データを全く損なわずに復元できるような圧縮方式のことである。
データを再び元の状態に戻せるところから、可逆圧縮とも呼ばれる。
テキストデータやプログラムのソースコードなどは、データがひとつでも変わると内容もはっきりと変わってくる。

(´・∀・`)ヘー

centosでロスレス圧縮を行うにはoptipngが必要のようなので、インストールの方を行います( ´∀`)bグッ!

ダウンロードします。
wget http://prdownloads.sourceforge.net/optipng/optipng-0.7.5.tar.gz?download
解凍します。
tar xzf optipng-0.7.5.tar.gz
解凍先のディレクトリへ移動する
cd optipng-0.7.5
stowを使ってインストールするためprefixを指定します。
sudo ./configure --prefix=/usr/local/stow/optipng-0.7.5
Checking for gcc...
Using pre-configured libpng...
Configuring zlib...
Checking for gcc...
Building static library libz.a version 1.2.8-optipng with gcc.
Checking for off64_t... Yes.
Checking for fseeko... Yes.
Checking for strerror... Yes.
Checking for unistd.h... Yes.
Checking for stdarg.h... Yes.
Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf().
Checking for vsnprintf() in stdio.h... Yes.
Checking for return value of vsnprintf()... Yes.
Checking for attribute(visibility) support... Yes.
makeを行います。
sudo make
cd src/optipng && \
        make && \
        cd ../..
make[1]: ディレクトリ `/home/admin/optipng-0.7.5/src/optipng' に入ります
cd ../zlib && \
        make -f Makefile && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/zlib' に入ります
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o adler32.o adler32.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o crc32.o crc32.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o deflate.o deflate.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o infback.o infback.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o inffast.o inffast.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o inflate.o inflate.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o inftrees.o inftrees.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o trees.o trees.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o zutil.o zutil.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o compress.o compress.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o uncompr.o uncompr.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o gzclose.o gzclose.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o gzlib.o gzlib.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o gzread.o gzread.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o gzwrite.o gzwrite.c
ar rc libz.a adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o example example.o -L. libz.a
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o minigzip.o test/minigzip.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o minigzip minigzip.o -L. libz.a
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -D_FILE_OFFSET_BITS=64 -c -o example64.o test/example.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o example64 example64.o -L. libz.a
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -D_FILE_OFFSET_BITS=64 -c -o minigzip64.o test/minigzip.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o minigzip64 minigzip64.o -L. libz.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/zlib' から出ます
cd ../libpng && \
        make -f Makefile PNGLIBCONF_H_PREBUILT=pnglibconf.h.optipng && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/libpng' に入ります
cp pnglibconf.h.optipng pnglibconf.h
gcc -c -I../zlib  -O2 -Wall -Wextra -o png.o png.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngerror.o pngerror.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngget.o pngget.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngmem.o pngmem.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngpread.o pngpread.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngread.o pngread.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngrio.o pngrio.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngrtran.o pngrtran.c
pngrtran.c:97: 警告: ‘png_rtran_ok’ defined but not used
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngrutil.o pngrutil.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngset.o pngset.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngtrans.o pngtrans.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngwio.o pngwio.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngwrite.o pngwrite.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngwtran.o pngwtran.c
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngwutil.o pngwutil.c
ar rcs libpng.a png.o pngerror.o pngget.o pngmem.o pngpread.o pngread.o pngrio.o pngrtran.o pngrutil.o pngset.o pngtrans.o pngwio.o pngwrite.o pngwtran.o pngwutil.o
ranlib libpng.a
gcc -c -I../zlib  -O2 -Wall -Wextra -o pngtest.o pngtest.c
gcc  -L../zlib -o pngtest pngtest.o libpng.a -lz -lm
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/libpng' から出ます
cd ../opngreduc && \
        make -f Makefile libopngreduc.a && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/opngreduc' に入ります
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -o opngreduc.o opngreduc.c
ar cru libopngreduc.a opngreduc.o
ranlib libopngreduc.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/opngreduc' から出ます
cd ../gifread && \
        make -f Makefile libgifread.a && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/gifread' に入ります
gcc -c  -O2 -Wall -Wextra -o gifread.o gifread.c
ar cru libgifread.a gifread.o
ranlib libgifread.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/gifread' から出ます
cd ../pnmio && \
        make -f Makefile libpnmio.a && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/pnmio' に入ります
gcc -c  -O2 -Wall -Wextra -o pnmin.o pnmin.c
gcc -c  -O2 -Wall -Wextra -o pnmout.o pnmout.c
gcc -c  -O2 -Wall -Wextra -o pnmutil.o pnmutil.c
ar cru libpnmio.a pnmin.o pnmout.o pnmutil.o
ranlib libpnmio.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/pnmio' から出ます
cd ../minitiff && \
        make -f Makefile libminitiff.a && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/minitiff' に入ります
gcc -c  -O2 -Wall -Wextra -o tiffbase.o tiffbase.c
gcc -c  -O2 -Wall -Wextra -o tiffread.o tiffread.c
ar cru libminitiff.a tiffbase.o tiffread.o
ranlib libminitiff.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/minitiff' から出ます
cd ../pngxtern && \
        make -f Makefile libpngxtern.a && \
        cd ../optipng
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/pngxtern' に入ります
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxread.o pngxread.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxrbmp.o pngxrbmp.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxrgif.o pngxrgif.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxrjpg.o pngxrjpg.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxrpnm.o pngxrpnm.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxrtif.o pngxrtif.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxio.o pngxio.c
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxmem.o pngxmem.c
pngxmem.c: In function ‘pngx_malloc_rows_extended’:
pngxmem.c:37: 警告: データ型の範囲制限によって、比較が常に false となります
gcc -c  -O2 -Wall -Wextra -I../zlib -I../libpng -I../gifread -I../pnmio -I../minitiff -o pngxset.o pngxset.c
ar cru libpngxtern.a pngxread.o pngxrbmp.o pngxrgif.o pngxrjpg.o pngxrpnm.o pngxrtif.o pngxio.o pngxmem.o pngxset.o
ranlib libpngxtern.a
make[2]: ディレクトリ `/home/admin/optipng-0.7.5/src/pngxtern' から出ます
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o optipng.o optipng.c
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o optim.o optim.c
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o bitset.o bitset.c
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o ratio.o ratio.c
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o osys.o osys.c
gcc -c  -O2 -Wall -Wextra -I../cexcept -I../zlib -I../libpng -I../opngreduc -I../pngxtern -o wildargs.o wildargs.c
gcc -s -o optipng optipng.o optim.o bitset.o ratio.o osys.o wildargs.o ../opngreduc/libopngreduc.a ../pngxtern/libpngxtern.a ../libpng/libpng.a ../zlib/libz.a ../gifread/libgifread.a ../pnmio/libpnmio.a ../minitiff/libminitiff.a   -lm
make[1]: ディレクトリ `/home/admin/optipng-0.7.5/src/optipng' から出ます
インストールを行います。
sudo make install
cd src/optipng && \
        make install && \
        cd ../..
make[1]: ディレクトリ `/home/admin/optipng-0.7.5/src/optipng' に入ります
mkdir -p /usr/local/stow/optipng-0.7.5/bin
mkdir -p /usr/local/stow/optipng-0.7.5/man/man1
cp -f -p optipng /usr/local/stow/optipng-0.7.5/bin
cp -f -p man/optipng.1 /usr/local/stow/optipng-0.7.5/man/man1
make[1]: ディレクトリ `/home/admin/optipng-0.7.5/src/optipng' から出ます
prefixで指定したstowのディレクトリへ移動します。
cd /usr/local/stow
stowで関連付けを行います。
sudo stow -v optipng-0.7.5
インストールされたバージョンの確認します。
optipng -v
OptiPNG version 0.7.5
Copyright (C) 2001-2014 Cosmin Truta and the Contributing Authors.

This program is open-source software. See LICENSE for more details.

Portions of this software are based in part on the work of:
  Jean-loup Gailly and Mark Adler (zlib)
  Glenn Randers-Pehrson and the PNG Development Group (libpng)
  Miyasaka Masaru (BMP support)
  David Koblas (GIF support)

Using libpng version 1.6.10-optipng and zlib version 1.2.8-optipng
これで、インストールは完了( ´∀`)bグッ!

オプションの確認φ(゚Д゚ )フムフム…
optipng -h
Synopsis:
    optipng [options] files ...
Files:
    Image files of type: PNG, BMP, GIF, PNM or TIFF
Basic options:
    -?, -h, -help       show this help
    -o <level>          optimization level (0-7)                [default: 2]
    -v                  run in verbose mode / show copyright and version info
General options:
    -backup, -keep      keep a backup of the modified files
    -clobber            overwrite existing files
    -fix                enable error recovery
    -force              enforce writing of a new output file
    -preserve           preserve file attributes if possible
    -quiet, -silent     run in quiet mode
    -simulate           run in simulation mode
    -out <file>         write output file to <file>
    -dir <directory>    write output file(s) to <directory>
    -log <file>         log messages to <file>
    --                  stop option switch parsing
Optimization options:
    -f <filters>        PNG delta filters (0-5)                 [default: 0,5]
    -i <type>           PNG interlace type (0-1)
    -zc <levels>        zlib compression levels (1-9)           [default: 9]
    -zm <levels>        zlib memory levels (1-9)                [default: 8]
    -zs <strategies>    zlib compression strategies (0-3)       [default: 0-3]
    -zw <size>          zlib window size (256,512,1k,2k,4k,8k,16k,32k)
    -full               produce a full report on IDAT (might reduce speed)
    -nb                 no bit depth reduction
    -nc                 no color type reduction
    -np                 no palette reduction
    -nx                 no reductions
    -nz                 no IDAT recoding
Editing options:
    -snip               cut one image out of multi-image or animation files
    -strip <objects>    strip metadata objects (e.g. "all")
Optimization levels:
    -o0         <=>     -o1 -nx -nz                             (0 or 1 trials)
    -o1         <=>     -zc9 -zm8 -zs0 -f0                      (1 trial)
                (or...) -zc9 -zm8 -zs1 -f5                      (1 trial)
    -o2         <=>     -zc9 -zm8 -zs0-3 -f0,5                  (8 trials)
    -o3         <=>     -zc9 -zm8-9 -zs0-3 -f0,5                (16 trials)
    -o4         <=>     -zc9 -zm8 -zs0-3 -f0-5                  (24 trials)
    -o5         <=>     -zc9 -zm8-9 -zs0-3 -f0-5                (48 trials)
    -o6         <=>     -zc1-9 -zm8 -zs0-3 -f0-5                (120 trials)
    -o7         <=>     -zc1-9 -zm8-9 -zs0-3 -f0-5              (240 trials)
    -o7 -zm1-9  <=>     -zc1-9 -zm1-9 -zs0-3 -f0-5              (1080 trials)
Notes:
    The combination for -o1 is chosen heuristically.
    Exhaustive combinations such as "-o7 -zm1-9" are not generally recommended.
Examples:
    optipng file.png                                            (default speed)
    optipng -o5 file.png                                        (slow)
    optipng -o7 file.png                                        (very slow)
圧縮対象のファイルはPNG, BMP, GIF, PNM or TIFF形式みたいです(´・∀・`)ヘー

optipngの使い方は次のような感じです。

圧縮せずにシミレーションを行う。
optipng -simulate /tmp/exit.png
圧縮率を指定する。o1からo7段階で設定が出来る。(デフォルトはo2で、最高圧縮はo7)
optipng -simulate -o7 /tmp/exit.png
バックアップを作成して圧縮を行う
optipng -backup -o7 /tmp/exit.png
** Processing: /tmp/exit.png
224x54 pixels, 4x8 bits/pixel, RGB+alpha, interlaced
Reducing image to 8 bits/pixel, 191 colors (83 transparent) in palette
Stripping metadata...
Input IDAT size = 7328 bytes
Input file size = 7422 bytes

Trying:
  zc = 9  zm = 9  zs = 0  f = 0         IDAT size = 3965
  zc = 9  zm = 8  zs = 0  f = 0         IDAT size = 3965

Selecting parameters:
  zc = 9  zm = 8  zs = 0  f = 0         IDAT size = 3965

Output IDAT size = 3965 bytes (3363 bytes decrease)
Output file size = 4702 bytes (2720 bytes = 36.65% decrease)
36%ほど圧縮されるっぽいですъ(゚Д゚)グッジョブ!!

メタ情報を削除した方がサイズが小さくなるので、
必ず-strip allオプションをつけた方が良いかもです( ´∀`)bグッ!
optipng -backup -o7 -strip all /tmp/exit.png
指定したディレクトリにあるpng画像全てを圧縮する場合には、次のようなコマンドで一括で変更できます。 (バックアップがいらない場合には-backupをはずすこと)
find /tmp/ -name "*.png" -print | xargs optipng -backup -o7 -strip all


念のため作業ディレクトリを作ってそちらで作業する場合(gif版)
mdir -p /tmp/gif
ディレクトリ構造を一時して指定されたファイルのみコピーする
find /tmp/original -name "*.gif" -print0 | xargs -0 cp --parents -t /tmp/gif/
xargsを使うとエラーが出てしまっていた・・・orz
find /tmp/gif -name "*.gif" | xargs optipng -o7 -strip all -out {} {} > /tmp/lossres.log 2>&1
** Error: The option -out requires one input file
execを利用する
find /tmp/gif -name "*.gif" -exec optipng -o7 -strip all -out {} {} \; > /tmp/lossres.log 2>&1

以上です(`・ω・´)ゞビシッ!!

参考URL

jsファイルの結合&圧縮を行う

前回からの続きです!
Gruntを使ってみる
今回は、Gruntを使ってjsファイルの結合&圧縮を行いたいと思います+(0゚・∀・) + ワクテカ +

前回gruntの作業ディレクトリとして作成した、
C:\node.js\gruntに新しくjsというフォルダを作っておきます。
その中に今回結合を行いたいjsファイルを配置して行きます。

まずは、結合対象のjsファイルを作成したいと思います。
C:\node.js\grunt\js\js01.jsを新規ファイルで作成して、jsのコードを適当に記述します。
$(function(){
 
    var boxW = $('.box').width();
    var boxH = $('.box').height();
  
});
C:\node.js\grunt\js\js02.jsを新規ファイルで作成して、jsのコードを適当に記述します。
$(function(){
 
    var boxIW = $('.box').innerWidth();
    var boxIH = $('.box').innerHeight();
 
});
次にC:\node.js\grunt\Gruntfile.jsを新規ファイルで作成して、Gruntの設定を記述します。

ファイルの結合にはgrunt-contrib-concatというプラグインを使う必要があります。

concatプラグインのsrcに結合するファイルを記述する。
concatのdestに結合後のファイル名を記述する。
※distは任意の名前で問題ない。

watchには監視して欲しいファイルと実行したいタスクを記述する。
module.exports = function(grunt) {
 
  grunt.initConfig({
 
    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
          dest : 'js/main.js'
        }
    },
    watch: {
      dev: {
        files: ["js/js*.js"],
        tasks: ['concat']
      }
    }
 
  });
 
  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
 
};
この状態でコマンドプロンプトにgrunt watchを入力して起動させ、
js01.js、またはjs02.jsを変更すると結合したmain.jsが作成されます。
C:\node.js\grunt>grunt watch
Running "watch" task
Waiting...
>> File "js\js01.js" changed.
Running "concat:dist" (concat) task
File js/main.js created.
念のため、main.jsの中身を確認する
$(function(){
 
    var boxW = $('.box').width();
    var boxH = $('.box').height();
  
});
$(function(){
 
    var boxIW = $('.box').innerWidth();
    var boxIH = $('.box').innerHeight();
 
});
今回の設定だと、監視対象のファイルを更新しないと結合ファイルが作成されないので、
起動時に生成するようにGruntfile.jsに起動時に実行させるタスクの行を追加します。
module.exports = function(grunt) {
 
  grunt.initConfig({
    //ファイルの結合
    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
          dest : 'js/main.js'
        }
    },
    //ファイルの監視
    watch: {
      dev: {
        files: ["js/js*.js"],
        tasks: ['concat']
      }
    }
 
  });
 
  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');

  //Grunt起動時に実行させるタスク
  grunt.registerTask('default', ['concat', 'watch']); 

};

これで、Gruntが起動したタイミングでも結合が実行されるようになりました。
実行すると次のようになります。
C:\node.js\grunt>grunt
Running "concat:dist" (concat) task
File js/main.js created.

Done, without errors.
結合が出来たので、次はjsを圧縮をしたいと思います。
先ほどのjs01.jsとjs02.jsを結合して出来たmain.jsを圧縮して、main-min.jsを作成したいと思います。

jsの圧縮にはgrunt-contrib-uglifyプラグインを利用するため、
grunt-contrib-uglifyプラグインを読み込む必要があります。
module.exports = function(grunt) {
 
  grunt.initConfig({

    //ファイルの圧縮
    uglify: {
      dist: {
        src: "js/main.js",
         dest: "js/main-min.js"
      }
    },
    //ファイルの結合
    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
        dest : 'js/main.js'
      }
    },
    //ファイルの監視
    watch: {
      dev: {
        files: ["js/js*.js"],
        tasks: ['concat', 'uglify']
      }
    }
 
  });
 
  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  //起動時に指定したタスクを実行する
  grunt.registerTask('default', ['concat', 'uglify', 'watch']);

};
実行してみると、次のような表示がされると思います。
C:\node.js\grunt>grunt
Running "concat:dist" (concat) task
File js/main.js created.

Running "uglify:dist" (uglify) task
File js/main-min.js created: 205 B → 114 B

Done, without errors.
main-min.jsの中身を確認してみると・・・圧縮(゚∀゚)キタコレ!!
$(function(){$(".box").width(),$(".box").height()}),$(function(){$(".box").innerWidth(),$(".box").innerHeight()});
これで、jsの結合・圧縮が無事に行えるようになりました( ´∀`)bグッ!
便利過ぎるワーイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワーイ

次回起動する時の注意として、
DOSKEY grunt=grunt.cmd $*
を実行しないと「grunt」では動いてくれないそうなので注意らしいです。
一回一回、上記のコマンドが面倒な場合はgrunt.cmdで実行するらしいヘー(´ν_.` )ソウナンダ

ファイルを結合、圧縮を複数やりたい場合には次のように記述します。
module.exports = function(grunt) {
 
  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({

    //ファイルの圧縮
    uglify: {
      dist1: {
        src: "js/main1.js",
         dest: "js/main1-min.js"
      },
      dist2: {
        src: "js/main2.js",
         dest: "js/main2-min.js"
      }
    },
    //ファイルの結合
    concat : {
      dist1 : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
        dest : 'js/main1.js'
      },
      dist2 : {
        src : [
          'js/js03.js',
          'js/js04.js'
        ],
        dest : 'js/main2.js'
      },
    },
    //ファイルの監視
    watch: {
      dev: {
        files: ["js/js*.js"],
        tasks: ['concat', 'uglify']
      }
    }
 
  });
 
  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  //起動時に指定したタスクを実行する
  grunt.registerTask('default', ['concat', 'uglify', 'watch']);

};
実行結果。

C:\node.js\grunt>grunt
Running "concat:dist1" (concat) task
File js/main1.js created.

Running "concat:dist2" (concat) task
File js/main2.js created.

Running "uglify:dist1" (uglify) task
File js/main1-min.js created: 205 B → 114 B

Running "uglify:dist2" (uglify) task
File js/main2-min.js created: 205 B → 114 B

Done, without errors.

以上です(`・ω・´)ゞビシッ!!

参考URL

Gruntを使ってみる

Google先生のPageSpeed Insightsに作ったサイトを解析してもらうと、
jsやcssはなるべく1つにまとめて圧縮してください( ‘д‘⊂彡☆))Д´) パーン
と怒られてしまうので、それを改善したい!(゚д゚)(。_。)(゚д゚)(。_。) ウンウン

今までは手動で結合・圧縮を行わないといけないと思っていたので、
メンテナンスが大変と事もありやっていませんでした(; ・`д・´)

ただ、社内的な事情でどうしてもやらないと行けなくなったので、
便利なツールが無いかな~と思ったら・・・Gruntという便利そうなものをハヶ━m9( ゚д゚)っ━ン!!

早速、使ってみました( ´∀`)bグッ!

まずはnode.jsのインストールを行います。
node.jsのダウンロード

公式サイトに行って、「download」をクリックします。

次に、各環境にあわせたファイルをダウンロードします。

 ダウンロードが終わったら、インストールを行います。

インストール画面では基本的に何も変更せずにNextやYesを押せば問題ありません。

同意画面

インストール先の設定画面

セットアップの変更画面

インストール開始画面




インストール完了画面


インストールが完了したら、Windowsの場合にはコマンドプロンプトを管理者として実行します。
スタートメニューにあるコマンドプロンプトを右クリックして「管理者として実行」を選択する。


コマンドプロンプトが立ち上がったら、
node -v
と入力すると、バージョンが表示されれば、正常にインストールが完了しています( ´∀`)bグッ!
C:\Windows\system32>node -v
v0.10.31
grunt-cliをインストール
C:\Windows\system32>npm install -g grunt-cli
C:\Users\nakajima\AppData\Roaming\npm\grunt -> C:\Users\nakajima\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt
grunt-cli@0.1.13 C:\Users\nakajima\AppData\Roaming\npm\node_modules\grunt-cli
├── resolve@0.3.1
├── nopt@1.0.10 (abbrev@1.0.5)
└── findup-sync@0.1.3 (lodash@2.4.1, glob@3.2.11)
作業ディレクトリをどこかに作成して、そのディレクトリへ移動します。
今回は、C:\node.js\gruntに作成してからコマンドプロンプトで移動しています。
C:\node.js>cd C:\node.js\grunt
作業ディレクトリの初期化を行います。行うとpackage.jsonファイルやディレクトリが作成されます。 初期化の際に項目の設定を聞かれますが、特に何もしていないでEnterを押してスキップしてしまいます(; ・`д・´)
C:\node.js\grunt>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (grunt)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\node.js\grunt\package.json:

{
  "name": "grunt",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
package.jsonが作られている確認
C:\node.js\grunt のディレクトリ

2014/09/05  22:24    <DIR>          .
2014/09/05  22:24    <DIR>          ..
2014/09/05  22:24               201 package.json
               1 個のファイル                 201 バイト
               2 個のディレクトリ  262,197,243,904 バイトの空き領域
package.jsonの中身の確認
C:\node.js\grunt>type package.json
{
  "name": "grunt",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
フォルダにgruntをインストール
C:\node.js\grunt>npm install grunt -save-dev
npm WARN package.json grunt@1.0.0 No description
npm WARN package.json grunt@1.0.0 No repository field.
npm WARN package.json grunt@1.0.0 No README data
npm WARN install Refusing to install grunt as a dependency of itself
package.jsonの中身を確認して、"devDependencies": {}が追加されていることを確認する。
C:\node.js\grunt>type package.json
{
  "name": "grunt",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {}
}
Windows7で便利なコマンドを実行しておく良いそうです(´・∀・`)ヘー こちらのサイトから抜粋 今更だけどやるgrunt入門編・インストールから基本的な使い方
Windows7だとgruntを実行する場合、「grunt」だけではダメで「grunt.cmd」としないと実行されません。前にやった時はここで詰まっていたようです。情報を調べるとみんなMacなのかあまりこの情報を見かけませんでした。 なのでここから先便利なように以下のコマンドを実行しておきます。
C:\node.js\grunt>DOSKEY grunt=grunt.cmd $*
プラグインのインストール
C:\node.js\grunt>npm install grunt-contrib -save-dev
npm WARN package.json grunt@1.0.0 No description
npm WARN package.json grunt@1.0.0 No repository field.
npm WARN package.json grunt@1.0.0 No README data
npm WARN deprecated grunt-contrib@0.11.0: DEPRECATED. See readme: https://github.com/gruntjs/grunt-contrib
npm WARN deprecated grunt-lib-contrib@0.7.1: DEPRECATED. See readme: https://github.com/gruntjs/grunt-lib-contrib
npm WARN deprecated es5-shim@2.3.0: Please update to the latest version; it overrides noncompliant native methods even in modern implementations
npm WARN deprecated deflate-crc32-stream@0.1.2: module has been merged into crc32-stream
\


> phantomjs@1.9.7-15 install C:\node.js\grunt\node_modules\grunt-contrib-qunit\node_modules\grunt-lib-phantomjs\node_modules\phantomjs
> node install.js

Downloading https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-windows.zip
Saving to C:\Users\nakajima\AppData\Local\Temp\phantomjs\phantomjs-1.9.7-windows.zip
Receiving...
\ [=====================================---] 94% 0.0s-
Received 6823K total.
Extracting zip contents
Copying extracted folder C:\Users\nakajima\AppData\Local\Temp\phantomjs\phantomjs-1.9.7-windows.zip-extract-1409923893866\phantomjs-1.9.7-windows -> C:\node.js\
grunt\node_modules\grunt-contrib-qunit\node_modules\grunt-lib-phantomjs\node_modules\phantomjs\lib\phantom
Writing location.js file
Done. Phantomjs binary available at C:\node.js\grunt\node_modules\grunt-contrib-qunit\node_modules\grunt-lib-phantomjs\node_modules\phantomjs\lib\phantom\phanto
mjs.exe

> phantomjs@1.9.7-15 install C:\node.js\grunt\node_modules\grunt-contrib-jasmine\node_modules\grunt-lib-phantomjs\node_modules\phantomjs
> node install.js

Download already available at C:\Users\nakajima\AppData\Local\Temp\phantomjs\phantomjs-1.9.7-windows.zip
Extracting zip contents
Copying extracted folder C:\Users\nakajima\AppData\Local\Temp\phantomjs\phantomjs-1.9.7-windows.zip-extract-1409923898612\phantomjs-1.9.7-windows -> C:\node.js\
grunt\node_modules\grunt-contrib-jasmine\node_modules\grunt-lib-phantomjs\node_modules\phantomjs\lib\phantom
Writing location.js file
Done. Phantomjs binary available at C:\node.js\grunt\node_modules\grunt-contrib-jasmine\node_modules\grunt-lib-phantomjs\node_modules\phantomjs\lib\phantom\phan
tomjs.exe

> jpegtran-bin@0.2.8 postinstall C:\node.js\grunt\node_modules\grunt-contrib-imagemin\node_modules\imagemin\node_modules\imagemin-jpegtran\node_modules\jpegtran
-bin
> node index.js

√ pre-build test passed successfully!

> pngquant-bin@0.3.5 postinstall C:\node.js\grunt\node_modules\grunt-contrib-imagemin\node_modules\imagemin\node_modules\imagemin-pngquant\node_modules\pngquant
-bin
> node index.js

√ pre-build test passed successfully!

> optipng-bin@0.3.11 postinstall C:\node.js\grunt\node_modules\grunt-contrib-imagemin\node_modules\imagemin\node_modules\imagemin-optipng\node_modules\optipng-b
in
> node index.js

√ pre-build test passed successfully!

> gifsicle@0.1.7 postinstall C:\node.js\grunt\node_modules\grunt-contrib-imagemin\node_modules\imagemin\node_modules\imagemin-gifsicle\node_modules\gifsicle
> node index.js

√ pre-build test passed successfully!
grunt-contrib-copy@0.5.0 node_modules\grunt-contrib-copy

grunt-contrib-symlink@0.3.0 node_modules\grunt-contrib-symlink

grunt-contrib-requirejs@0.4.4 node_modules\grunt-contrib-requirejs
└── requirejs@2.1.14

grunt-contrib-clean@0.5.0 node_modules\grunt-contrib-clean
└── rimraf@2.2.8

grunt-contrib-csslint@0.2.0 node_modules\grunt-contrib-csslint
└── csslint@0.10.0 (parserlib@0.2.5)

grunt-contrib-htmlmin@0.2.0 node_modules\grunt-contrib-htmlmin
├── each-async@0.1.3
├── pretty-bytes@0.1.2
├── html-minifier@0.5.6
└── chalk@0.4.0 (ansi-styles@1.0.0, strip-ansi@0.1.1, has-color@0.1.7)

grunt-contrib-compass@0.7.2 node_modules\grunt-contrib-compass
├── dargs@0.1.0
├── tmp@0.0.23
└── async@0.2.10

grunt-contrib-sass@0.7.4 node_modules\grunt-contrib-sass
├── dargs@0.1.0
├── win-spawn@2.0.0
├── which@1.0.5
├── async@0.9.0
└── chalk@0.5.1 (escape-string-regexp@1.0.1, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)

grunt-contrib-concat@0.4.0 node_modules\grunt-contrib-concat
└── chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)

grunt-contrib-watch@0.6.1 node_modules\grunt-contrib-watch
├── async@0.2.10
├── gaze@0.5.1 (globule@0.1.0)
├── tiny-lr-fork@0.0.5 (debug@0.7.4, faye-websocket@0.4.4, noptify@0.0.3, qs@0.5.6)
└── lodash@2.4.1

grunt-contrib-cssmin@0.9.0 node_modules\grunt-contrib-cssmin
├── clean-css@2.1.8 (commander@2.1.0)
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
└── maxmin@0.1.0 (pretty-bytes@0.1.2, gzip-size@0.1.1)

grunt-contrib-uglify@0.4.1 node_modules\grunt-contrib-uglify
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
├── maxmin@0.1.0 (pretty-bytes@0.1.2, gzip-size@0.1.1)
└── uglify-js@2.4.15 (uglify-to-browserify@1.0.2, async@0.2.10, optimist@0.3.7, source-map@0.1.34)

grunt-contrib-jst@0.6.0 node_modules\grunt-contrib-jst
├── lodash@2.4.1
├── chalk@0.4.0 (has-color@0.1.7, strip-ansi@0.1.1, ansi-styles@1.0.0)
└── grunt-lib-contrib@0.7.1 (strip-path@0.1.1, maxmin@0.1.0)

grunt-contrib-jade@0.11.0 node_modules\grunt-contrib-jade
├── grunt-lib-contrib@0.6.1 (zlib-browserify@0.0.1)
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
└── jade@1.2.0 (commander@2.1.0, character-parser@1.2.0, mkdirp@0.3.5, constantinople@2.0.1, transformers@2.1.0, with@2.0.0, monocle@1.1.51)

grunt-contrib-jshint@0.10.0 node_modules\grunt-contrib-jshint
├── hooker@0.2.3
└── jshint@2.5.5 (strip-json-comments@0.1.3, underscore@1.6.0, exit@0.1.2, console-browserify@1.1.0, shelljs@0.3.0, minimatch@0.4.0, cli@0.6.4, htmlparser2@3
.7.3)

grunt-contrib-coffee@0.10.1 node_modules\grunt-contrib-coffee
├── chalk@0.4.0 (strip-ansi@0.1.1, ansi-styles@1.0.0, has-color@0.1.7)
├── lodash@2.4.1
└── coffee-script@1.7.1 (mkdirp@0.3.5)

grunt-contrib-handlebars@0.8.0 node_modules\grunt-contrib-handlebars
├── grunt-lib-contrib@0.5.3 (zlib-browserify@0.0.1)
├── chalk@0.4.0 (strip-ansi@0.1.1, ansi-styles@1.0.0, has-color@0.1.7)
└── handlebars@1.3.0 (optimist@0.3.7, uglify-js@2.3.6)

grunt-contrib-connect@0.7.1 node_modules\grunt-contrib-connect
├── connect-livereload@0.3.2
├── async@0.2.10
├── open@0.0.4
├── portscanner@0.2.2 (async@0.1.15)
└── connect@2.13.1 (uid2@0.0.3, methods@0.1.0, pause@0.0.1, debug@0.8.1, cookie-signature@1.0.1, qs@0.6.6, fresh@0.2.0, bytes@0.2.1, raw-body@1.1.3, buffer-c
rc32@0.2.1, batch@0.5.0, cookie@0.1.0, compressible@1.0.0, negotiator@0.3.0, send@0.1.4, multiparty@2.2.0)

grunt-contrib-nodeunit@0.3.3 node_modules\grunt-contrib-nodeunit

grunt-contrib-stylus@0.15.1 node_modules\grunt-contrib-stylus
├── async@0.8.0
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
├── nib@1.0.3 (stylus@0.37.0)
├── stylus@0.44.0 (css-parse@1.7.0, debug@2.0.0, sax@0.5.8, glob@3.2.11, mkdirp@0.3.5)
└── lodash@2.4.1

grunt-contrib-qunit@0.4.0 node_modules\grunt-contrib-qunit
└── grunt-lib-phantomjs@0.5.0 (eventemitter2@0.4.14, semver@1.0.14, temporary@0.0.8, phantomjs@1.9.7-15)

grunt@0.4.5 node_modules\grunt
├── dateformat@1.0.2-1.2.3
├── which@1.0.5
├── eventemitter2@0.4.14
├── getobject@0.1.0
├── colors@0.6.2
├── rimraf@2.2.8
├── async@0.1.22
├── grunt-legacy-util@0.2.0
├── hooker@0.2.3
├── exit@0.1.2
├── nopt@1.0.10 (abbrev@1.0.5)
├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
├── lodash@0.9.2
├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
├── coffee-script@1.3.3
├── underscore.string@2.2.1
├── iconv-lite@0.2.11
├── grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.1)
├── findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.1)
└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)

grunt-contrib-compress@0.8.0 node_modules\grunt-contrib-compress
├── prettysize@0.0.3
└── archiver@0.8.1 (buffer-crc32@0.2.3, lazystream@0.1.0, readable-stream@1.0.31, zip-stream@0.3.7, file-utils@0.1.5, lodash@2.4.1)

grunt-contrib-less@0.11.4 node_modules\grunt-contrib-less
├── async@0.2.10
├── chalk@0.5.1 (escape-string-regexp@1.0.1, ansi-styles@1.1.0, supports-color@0.2.0, has-ansi@0.1.0, strip-ansi@0.3.0)
├── maxmin@0.1.0 (pretty-bytes@0.1.2, chalk@0.4.0, gzip-size@0.1.1)
├── lodash@2.4.1
└── less@1.7.5 (graceful-fs@3.0.2, mime@1.2.11, mkdirp@0.5.0, source-map@0.1.38, clean-css@2.2.15, request@2.40.0)

grunt-contrib-jasmine@0.6.5 node_modules\grunt-contrib-jasmine
├── rimraf@2.1.4 (graceful-fs@1.2.3)
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
├── es5-shim@2.3.0
├── lodash@2.4.1
└── grunt-lib-phantomjs@0.4.0 (eventemitter2@0.4.14, semver@1.0.14, temporary@0.0.8, phantomjs@1.9.7-15)

grunt-contrib-imagemin@0.7.2 node_modules\grunt-contrib-imagemin
├── pretty-bytes@0.1.2
├── async@0.7.0
├── chalk@0.4.0 (has-color@0.1.7, strip-ansi@0.1.1, ansi-styles@1.0.0)
└── imagemin@0.4.9 (stat-mode@0.2.0, ware@0.3.0, rimraf@2.2.8, tempfile@0.1.3, nopt@3.0.1, image-type@0.1.4, fs-extra@0.10.0, imagemin-svgo@0.1.1, imagemin-j
pegtran@0.1.0, imagemin-pngquant@0.1.3, imagemin-optipng@0.1.0, imagemin-gifsicle@0.1.1)

grunt-contrib-yuidoc@0.5.2 node_modules\grunt-contrib-yuidoc
└── yuidocjs@0.3.50 (rimraf@2.2.8, graceful-fs@2.0.3, marked@0.2.10, minimatch@0.2.14, express@3.1.2, yui@3.14.1)

grunt-contrib@0.11.0 node_modules\grunt-contrib
└── matchdep@0.3.0 (stack-trace@0.0.7, resolve@0.5.1, globule@0.1.0, findup-sync@0.1.3)

プラグインが追加されたか確認する
C:\node.js\grunt>type package.json
{
  "name": "grunt",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib": "^0.11.0",
    "grunt-contrib-clean": "^0.5.0",
    "grunt-contrib-coffee": "^0.10.1",
    "grunt-contrib-compass": "^0.7.2",
    "grunt-contrib-compress": "^0.8.0",
    "grunt-contrib-concat": "^0.4.0",
    "grunt-contrib-connect": "^0.7.1",
    "grunt-contrib-copy": "^0.5.0",
    "grunt-contrib-csslint": "^0.2.0",
    "grunt-contrib-cssmin": "^0.9.0",
    "grunt-contrib-handlebars": "^0.8.0",
    "grunt-contrib-htmlmin": "^0.2.0",
    "grunt-contrib-imagemin": "^0.7.2",
    "grunt-contrib-jade": "^0.11.0",
    "grunt-contrib-jasmine": "^0.6.5",
    "grunt-contrib-jshint": "^0.10.0",
    "grunt-contrib-jst": "^0.6.0",
    "grunt-contrib-less": "^0.11.4",
    "grunt-contrib-nodeunit": "^0.3.3",
    "grunt-contrib-qunit": "^0.4.0",
    "grunt-contrib-requirejs": "^0.4.4",
    "grunt-contrib-sass": "^0.7.4",
    "grunt-contrib-stylus": "^0.15.1",
    "grunt-contrib-symlink": "^0.3.0",
    "grunt-contrib-uglify": "^0.4.1",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-contrib-yuidoc": "^0.5.2"
  }
}
これで、インストールは完了ですワーイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワーイ
早速Gruntを実行してみたいと思います!

Gruntfile.jsを新規作成する
今回は、C:\node.js\grunt\Gruntfile.jsに新規ファイルを作って次の記述を書きました。
この記述を書くことで指定されたファイルが更新されたことを通知しくれるようになりますヘー(´ν_.` )ソウナンダ

module.exports = function(grunt) {
  //グラントタスクの設定
  grunt.initConfig({
    //watchの設定
    watch: {
      dev: {
        files: ["sample.txt"]
      }
    }
  });
  //プラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
};
sample.txtを新規作成する
今回はC:\node.js\grunt\sample.txtに新規で空ファイルを作成しました。
gruntを実行する。次のようにWaiting...と表示されれば監視が正常に開始されています。
C:\node.js\grunt>grunt watch
Running "watch" task
Waiting...
監視がされたらsample.txtの中身を適当に文字などを入力して保存します。
そうするとコマンドプロンプトの画面にsample.txtが変わったことを通次のように通知してくれます。スゲ━━━━━━ヽ(゚Д゚)ノ━━━━━━!!!!

C:\node.js\grunt>grunt watch
Running "watch" task
Waiting...
>> File "sample.txt" changed.
Completed in 0.001s at Fri Sep 05 2014 22:42:09 GMT+0900 (東京 (標準時)) - Waiting...
中断は「control+C」を入力しgrunt watchを中断できます。
C:\node.js\grunt>grunt watch
Running "watch" task
Waiting...
>> File "sample.txt" changed.
Completed in 0.001s at Fri Sep 05 2014 22:42:09 GMT+0900 (東京 (標準時)) - Waiting...
^Cバッチ ジョブを終了しますか (Y/N)? y
キタ――(゚∀゚)――!!

ひとまず、これでGruntによるファイル更新のチェックが行えるようになりました。
次回は、jsファイルの結合・圧縮を行いたいと思います(ΦωΦ)フフフ…

以上です(`・ω・´)ゞビシッ!!

参考URL

2014年8月26日火曜日

メモリリークの解析ツール ダウンロード・インストール方法

■ メモリの調査 ツールの導入 MAT memory analyzer tool


OutOfMemmoryErrorがたまにでるので、どのくらいメモリを食べているのか調査するために便利そうなツールを探しているとこんなものを発見φ(・ω・)カキカキ
導入方法をメモします。

● ダウンロード ----------------------------------------------

   Memory Analyzer 
   メモリの使用状況がわかるもの
   Eclipseで使うMemory Analyzerのインストール ↓
   http://xiangcai.at.webry.info/201009/article_7.html

● ecripseにインストールする --------------------------------

Help > Install New Software Avaliable software sites(使用可能なソフトウェアサイト一覧)  
   追加しインストールする
   > http://download.eclipse.org/birt/update-site/4.3/
     BIRT 4.3 Engine OSGi Runtime SDK のみ選択する

   > http://download.eclipse.org/mat/1.4/update-site/
     すべてインストールする


● 使用方法 --------------------------------------------------

アプリを起動

   Window → Open Persepective → DDMS または、右上のDDMSボタンを押下

   ヒープファイルを作成する
  DDMS → Dump HPROF file クリック(左上にだいたいある)

 ↓
   Leak Suspects Reportを選択し完了
    ↓
  Leak Suspectsタブの左上のグラフ(三本線)を押下すると詳細がみれます


 場所は以下のとおりです。↓
  















以上ですく(・ω・)


 



2014年8月22日金曜日

現在のスレッドがUI(メイン)かチェックする



現在のスレッドがメインか、その他のワーカスレッドがどっちかわからなくなった時用に…
メモしますφ(。_。)カキカキ


こいつで現在のスレッドを取得して↓

Thread.currentThread();

メインのスレッドと比較する↓

getMainLooper().getThread();

if( Thread.currentThread.equals( getMainLooper().getThread() ) ){
     //メインきた!
}

以上です(。ω。)


 参考サイト
http://blog.livedoor.jp/sylc/archives/1564156.html

2014年8月21日木曜日

setEmptyViewを使用する際の注意点(設定しても何も起こらない件)



メインレイアウトの中にListViewを配置して、setEmptyViewが反応しない…ということがあったのでメモしますφ(・ω・`)カリカリ

■ xml側の記述

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/MainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >


   <TextView
          android:layout_width="match_parent"
           android:layout_height="wrap_content"
          android:text="@string/employee_name" />

   <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />



</LinearLayout>




■ ソース側の記述
ListView list = view.findViewById(R.id.list);

/* その他もろもろの設定処理 省略します */

//んで最後にadapterが空になった時に表示するViewを設定すると…

LinearLayout.LayoutParams params = new LinerLayout.LayoutParams( ViewGroup.LayoutParams.MATH_PARENT, ViewGroup.LayoutParams.MATH_PARENT );
TextView text = new TextView( getActivity() );
text.setText( "ないよ~~~~" );
text.setLayoutParams(params);

list.setEmptyView( text );


設定すると…でてくるはず!!…って あれ…何もおこらない(・ω・?) ん?なぜ?
先輩に送ってくれたサイトをちらちら…
http://qiita.com/ryugoo/items/b8b735e3c441c65bdaa8
このサイトでヒントをいただきましたm(。_。)m
アリガトウゴザイマス。
…んで修正修正とφ(。_。)カタカタ

■ xml側の記述

とりあえずListViewの親にFrameLayoutを設置していれこにします。
 <TextView
          android:layout_width="match_parent"
           android:layout_height="wrap_content"
          android:text="@string/employee_name" />

  <FrameLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:layout_weight="3" >

        <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>


■ ソース側の記述
LinearLayout.LayoutParams params = new LinerLayout.LayoutParams( ViewGroup.LayoutParams.MATH_PARENT, ViewGroup.LayoutParams.MATH_PARENT );
TextView text = new TextView( getActivity() );
text.setText( "ないよ~~~~" );
text.setLayoutParams(params);

list.setEmptyView( text );


//親ビューにemptyViewを追加します。
 ((ViewGroup)list.getParent()).addView( text );//←ここにこれを追加するだけ!!


やったやった!!きたきた!!(@^ω^)
後、記述の注意点としてsetEmptyViewを呼び出し後にかならず親ビューへセットしてください。
 じゃなきゃエラーでます。(・ω・;)でちゃいますよ。
 んと、毎回毎回TextViewを作成するために記述するのがめんどくさかったのでListViewを継承カスタムViewを作成してその中で作るように変えました。
(・_・)もっといい方法ないかなぁ。 以上です。m(._.)m

2014年8月18日月曜日

TextWatcherインターフェースを使用して、リアルタイムにEditTextの内容を取得する


今回EditTextに入力されたものを、リアルタイムにチェックを行う必要があったので

onKeyListener,OnEditorActionListenerは使用せず、一定の間隔で処理を実行しようと考えているところこんなインターフェース「TextWatcher」を発見(・ω・!!!)


使用しているActivityまたは、Fragmentにimplementsして…[ import android.text.TextWatcher; ]
abstract指定されてる関数を実装します(・ω・)フムフム


//操作後のEtidTextの状態を取得する
public abstract void afterTextChanged (Editable s) 

//操作前のEtidTextの状態を取得する public abstract void beforeTextChanged (CharSequence s, int start, int count, int after)

 //操作中のEtidTextの状態を取得する
public abstract void onTextChanged (CharSequence s, int start, int before, int count) 


EditTextにリスナーをセットして終わり。(・0・)オーーーー
view.addTextChangedListener(this);


以上です(・ω・)



参考サイト
http://gupuru.hatenablog.jp/entry/2014/04/07/202334 http://developer.android.com/reference/android/text/TextWatcher.html

2014年8月1日金曜日

PHPによるセールスフォースAPI連携3(データローダによるCSV登録)

API連携から少し離れますがデータを一括登録したい場合は、SalesForceのデータインポートウィザードまたは、データローダを使い、CSVファイルにて一括登録が行えます。


データインポートウィザード  SalesForceメニューから利用  インポート上限:5万件 
データローダ  PCにインストール  インポート上限:500万件 





1. データインポートウィザードによる 一括登録

1.1. 「データの管理」 → 「データインポートウィザード」から、「ウィザードを起動する」をクリックします。


1.2. CSVファイルを準備します。
  
"OWNERID","名前"
"00510000003CfSkAAK","あいうえお0001"
"00510000003CfSkAAK","あいうえお0002"
"00510000003CfSkAAK","あいうえお0003"

1.3. オブジェクト名、CSVファイル、文字コードを選択します。


1.4. 対応付けの確認画面が表示されます。


1.5. 確認画面が表示されます。

1.6. インポートの完了メッセージが表示されます。




1.7. データが追加されます。














2. データローダによる一括登録

2.1.  「データの管理」 → 「データローダ」をクリックし、「データローダの設定」ページからデータローダをダウンロードをします。




2.2. ダウンロードした ApexDataLoader.exe を実行し、インストールを行います。





2.3. インストール完了です。




2.4. テスト用のCSVファイルを準備します。

test.csv
  
"NAME"
"かきくけこ"
"さしすせそ"
"たちつてと"

2.5.データローダを起動します。



2.6. 「Insert」をクリックします。

2.7. ログイン画面が開きます。

Username : SalesForceログイン時のユーザ名を入力します。
Password :  SalesForceログイン時のパスワード+セキュリティトークンを入力します。




2.8. ログインに成功すると、「Next」ボタンがクリックできるようになるのでクリックします。

2.9.  データを登録するオブジェクトを選択し、CSVファイル(test.csv)を選択し、「Next」をクリックします。

2.10. レコード追加の確認メッセージが表示されるので「OK」をクリックします。

2.11. マッピングの確認画面が表示されるので、「Create or Edit a Map」をクリックします。


2.12. マッピングの設定画面が表示されるので、「Auto-Match Fields to Columns」をクリックします。
画面下に、オブジェクトのNameとCSVファイルのNameのマッピングが設定されたら、「OK」をクリックします。


2.13. マッピングの確認画面に戻り、「Next」をクリックします。

2.14. 実行結果を保存するディレクトリの選択画面が表示されるので、 ディレクトリを指定して「Finish」をクリックします。


2.15.インサートの確認メッセージが表示されるので、「はい」をクリックします。


2.16.  実行結果のメッセージが表示されます。

「View Successes」 : 成功したデータの内容が表示さます。
「View Errors」 : エラー時のメッセージが表示されます。


2.17. データが登録されたことを確認します。















オブジェクトの登録データを一括削除したい場合

3.1.  「設定」 → 「ビルド」 → 「カスタマイズ」 → 「ユーザインタフェース」から、「カスタムオブジェクトの切捨てを有効化」をONにします。



1.2. 「設定」 → 「スキーマビルダー」からオブジェクトを選択し、「オブジェクトを参照する」をクリックする。

































1.3. オブジェクトの画面で「切り捨て」をクリックします。
(「カスタムオブジェクトの切捨てを有効化」がON の場合、「切り捨て」ボタンが出現します)





















1.4.  カスタムオブジェクトの切り捨て画面で、オブジェクトを指定して「切り捨て」をクリックすると、データが一括削除されます。


2014年7月31日木曜日

非同期通信 → コールバック実装 → Toastを表示する(ここでツマッタのでメモ)


非同期通信で画像を登録



コールバックonCompleteきた



Toast表示 !!!
ん?あれ表示されないし、intentも飛ばされない…orz



android特有でUIスレッド以外のスレッドではUIを操作することはできないことは、前調べた時に知っていたので handler.post() を使用して投げようと思ったところ…
UIのスレッドを特定すればいいのかわからず右往左往 (*ω*;)

調べてみたところ、こんな関数を発見!!

Activity#runOnUiThread()



UIのスレッドに投げてくれる便利な関数がActivityに用意されていました。
さっそく試してみる…


getActivity().runOnUiThread( new Runnable(){
         @Override
         public void run() {
               // TODO Auto-generated method stub
                  Toast.makeText(
                      getActivity(),
                      R.string.regist_complete,
                      Toast.LENGTH_SHORT).show();
                  Intent intent = new Intent( getActivity(), ******** );
                  getActivity().startActivity(intent);
          }
});



やったーーーー表示された!
遷移した!!\(^ω^)/

めでたしめでたいし。やっと次へ進めます。

以上です(・ω・)


■参考サイト
http://visible-true.blogspot.jp/2011/11/activityrunonuithreadrunnable.html


ほんと助かりました。アリガトウございます m(。_。)m

2014年7月30日水曜日

PHPによるセールスフォースAPI連携2(オブジェクト作成/データ登録)


1.セールスフォースでオブジェクトを新規作成する

1.1. 「スキーマビルダ」をクリックします。



































1.2. 「オブジェクト」タブで登録済みのオブジェクトが確認できます。




























 
1.3.  左カラムの「要素」タブを選択し、「オブジェクト」をドラック&ドロップするとオブジェクトが新規作成されます。




























1.4. 新規オブジェクト作成画面で、必要項目を登録します。







































1.5.オブジェクトが作成されます。


































1.6. オブジェクトに登録されているデータを確認するために、タブの設定を行います。
「設定」→「作成」→「タブ」「カスタムオブジェクトタブ」「新規」を押します。


1.7. オブジェクトを選択し、「次へ」を押して行きます。




















1.8. 登録が完了すると、ヘッダメニューにオブジェクト名のリンクが表示されます。






1.9. オブジェクト名のリンクをクリックすると、下記にデータが表示されます。(データが登録されると表示されます。)


2. PHPプログラムからデータをインサートする。

2.1. SQLで使用する、API参照名、項目名を調べる。
「設定」→「作成」→「オブジェクト」→「オブジェクト名」を押す。






















































2.2. プログラムを作成する。

  
<?php

// Toolkitを読込みます。
require_once("./soapclient/SforcePartnerClient.php");

// 事前に必要な情報を宣言します。

// 今回は特定のセールスフォース組織に依存しないような場合に利用する
// Partner WSDL ファイルを利用します。
define("PARTNER_WSDL_FILE", "./configs/partner.wsdl.xml");

// セールスフォースへAPI接続する場合、接続元のIPアドレス許可が必要となりますが、
// 代替手段として、今回はセキュリティトークンを発行してIPアドレス許可の設定はスキップします。
define("SECURITY_TOKEN", "************************");

// API でログインするセールスフォースのアカウントです。
define("LOGIN_ID", "*******@***.**.**");

// パスワードの後ろにセキュリティトークンを付けます。
define("LOGIN_PASS", "**********" . SECURITY_TOKEN);


// 接続用クラスを生成します。
$sforce_connection = new SforcePartnerClient(); 
$soap_client = $sforce_connection->createConnection(PARTNER_WSDL_FILE, null);

echo "<pre>";

try {
    // セールスフォースへログインを実行します。
    $login = $sforce_connection->login(LOGIN_ID, LOGIN_PASS);
    var_dump($login);

} catch (Exception $e) {
    var_dump($e);
}

// 追加するデータは stdClass を利用して作成します。
$insert_data = new stdClass();
$insert_data->type = "test01__c";
$insert_data->fields = array(
"Name" => "あいうえお", 
);
try {
$result = $sforce_connection->create(array($insert_data));
var_dump($result);

} catch (Exception $e) {
var_dump($e);
}

// 通常の SQL と大きく変わりませんが、少し独特な個所がありますので徐々に慣れていきましょう。
try {
$query = "SELECT id, name FROM test01__c";
$result = $sforce_connection->query($query);
$parse_result = get_object_vars($result);
var_dump($parse_result);

} catch (Exception $e) {
var_dump($e);
}


echo "<br />END</pre>";

?>


実行結果
 
array(1) {
  [0]=>
  object(stdClass)#9 (2) {
    ["id"]=>
    string(18) "a041000000TvX03AAF"
    ["success"]=>
    bool(true)
  }
}
array(5) {
  ["queryLocator"]=>
  NULL
  ["done"]=>
  bool(true)
  ["records"]=>
  array(1) {
    [0]=>
    object(stdClass)#10 (3) {
      ["type"]=>
      string(9) "test01__c"
      ["Id"]=>
      array(2) {
        [0]=>
        string(18) "a041000000TvX03AAF"
        [1]=>
        string(18) "a041000000TvX03AAF"
      }
      ["any"]=>
      string(34) "あいうえお"
    }
  }
  ["size"]=>
  int(1)
  ["pointer"]=>
  int(0)
}


2.3. 登録データを確認する。