• Facebook
  • Twitter
  • RSS
月別
コツコツあつめるWeb作りのためのたね たねっぱ!Web系情報ブログ Webのお役立ちネタ配信中!

【Gulp】pngquantで圧縮した画像がMacで暗くなる場合の対処法

投稿者アイコン
2016/08/25
書いた人:
tanippa!
カテゴリ:
Web制作
タグ
8,106 views

pngquantで圧縮した画像がMacのFirefox/Chromeで暗くなるという問題の原因と解決法に関してご紹介したいと思います。

【Gulp】pngquantで圧縮した画像がMacで暗くなる場合の対処法

自分はタスクランナーとしてGulpを利用しており、png画像の圧縮にはpngquantを使っているのですが、先日「MacのFirefoxとChromeだけ圧縮したpng画像の色が暗くなる」という状況に遭遇してしまいました。

色々調査した結果、原因と解決法がわかりましたので、今回はそれに関してご紹介したいと思います。

結論

Gulpでpngquantを使用する場合は以下のようにgulpfileを書いているかと思います。

var gulp = require('gulp');

var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');

gulp.task('img', function() {
  gulp.src('./src/**/*.png')
      .pipe(imagemin(
        [pngquant({
          quality: '60-80'
        })]
      ))
      .pipe(gulp.dest('./dist'));
});

これに1行追加する必要があります。

var gulp = require('gulp');

var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');

gulp.task('img', function() {
  gulp.src('./src/**/*.png')
      .pipe(imagemin(
        [pngquant({
          quality: '60-80'
        })]
      ))
      .pipe(imagemin()) //これを追加!
      .pipe(gulp.dest('./dist'));
});

詳細

理由ですが、特定のpng画像をpngquantで圧縮すると、画像にガンマ補正の情報が付加される場合があり、その場合MacのFirefox,GoogleChromeにおいて画像の色と周りの色に差が出る可能性があるからです。

実例として、以下のデモをMacのFirefoxかChromeで確認してみてください。

デモ

img01

※Windowsでも確認出来るよう、スクリーンショットも貼っておきます。

この画像は#ccccccで塗りつぶされており、デモの背景も#ccccccを指定しています。

にもかかわらず、圧縮後の画像はすこし暗くなってしまっており背景と差が出てしまってますね。

これは、pngquantが圧縮後にガンマ補正情報を付加してしまう時があるのが原因となっています。

実際に圧縮前、圧縮後の画像の詳細をプレビューで確認してみると以下の様な情報が出てきます。

圧縮前

img02

圧縮後

img03

圧縮後の画像には「ガンマ」という項目が増えてしまっていますね。これが原因で表示がおかしくなってしまっています。

この「ガンマ」に関して詳しく話すと結構ややこしい話になるのですが、解決法だけなら単純です。この「ガンマ」情報を除去すれば良いだけです。

除去する方法は色々あるのですが、gulp-imageminがpngを圧縮する時にデフォルトで使用されるoptipngが除去する仕様となっているので、これを利用したいと思います。

その際のgulpfileのソースコードは、冒頭にも記述しましたが以下のようになります。

var gulp = require('gulp');

var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');

gulp.task('img', function() {
  gulp.src('./src/**/*.png')
      .pipe(imagemin(
        [pngquant({
          quality: '60-80'
        })]
      ))
      .pipe(imagemin()) //ここでガンマ情報を除去!
      .pipe(gulp.dest('./dist'));
});

以上

pngquantは圧縮率が良いため利用しているのですが、今回の件以外にも落とし穴があったりして結構面倒です。
(qualityの下限を下回る圧縮が必要な画像に関しては圧縮がスキップされ、distディレクトリにコピーもされないため自前でコピー処理を記述する必要があったり…)

ですが、Gulpで自動化を行うことによって、圧縮漏れ等がなくなり成果物の質が担保されるというメリットがありますので、これにめげず積極的に自動化を進めたい次第です!

以上、たにっぱでした〜


この記事を読んだ人はこんな記事も読んでいます