76167


質問下部に添付したファイルを Windows8.1 ​の 「Windowsフォトビューアー」 で開くと  
「この画像をWindows フォトビューアーで表示できません。利用できる十分なメモリがない可能性があります。」  
というエラーになります。

しかし、スライドショー、ペイント、Chromeブラウザなどでファイルを開けば画像として正しく表示されます。  
Windows フォトビューアーで開いたときだけ画像が表示されません。

ICC_PROFILEというのが関係していることまでは原因を特定。  
Hex
Editorで画像を開き、ICC_PROFILEの部分をICC_PROFILAやICC_PROFILXなどに書き換えてやると、Windowsフォトビューアーでも画像が開けるようになりました。  
<https://www.pcreview.co.uk/threads/windows-photo-viewer-
can%E2%80%99t-display-this-picture-because-there-might-not-be-enough-memory-
available-on-your-computer.4075896/>

ここで質問です。  
**・jpgには、ICC_PROFILEを含むjpgと、ICC_PROFILEを含まないjpgがある  
（ICC_PROFILEというのはメタデータで、jpgファイルに必須のものではない）  
という認識で合っているでしょうか？**

**・javascriptでjpgファイルからICC_PROFILEを消すにはどうすればよいでしょうか？**

もともとのjpgファイルは、Node.jsのpuppeteerでブラウザのscreenshotを保存したものです。

・puppeteerでscreenshotを作成するときにICC_PROFILEを含まないjpgとして保存する  
もしくは  
・puppeteerでscreenshotを作成した時点ではICC_PROFILEありで、それをjavascript上でICC_PROFILEなしのjpgに変換する  
ということを実現したいです。

[![画像の説明をここに入力](https://i.stack.imgur.com/WYYbY.jpg)](https://i.stack.imgur.com/WYYbY.jpg)


CC BY-SA 4.0
2021-05-28T14:02:35.877
76156
2021-05-30T14:49:24.170
2021-05-28T14:08:01.363
45540
45540
question
javascript windows 画像 puppeteer 画像処理
JavascriptでjpgファイルのICC_PROFILEを消すには？


  * **jpgには、ICC_PROFILEを含むjpgと、ICC_PROFILEを含まないjpgがある（ICC_PROFILEというのはメタデータで、jpgファイルに必須のものではない）という認識で合っているでしょうか？**

認識は合っているでしょう。こんな記事があります。

[4.2 Color profile - JPEG -
Wikipedia](https://en.wikipedia.org/wiki/JPEG#Color_profile)

> Many JPEG files embed an ICC color profile (color space). Commonly used
> color profiles include sRGB and Adobe RGB.

「多くの」JPEGファイルには、となっているので必須では無いでしょう。

[カラースペースの変換と一般的なマーカー - JPEG
メタデータ形式の仕様および使用上の注意](https://docs.oracle.com/javase/jp/7/api/javax/imageio/metadata/doc-
files/jpeg_metadata.html#color)

> オプションの ColorSpace のサポート:

ColorSpaceはオプションと書かれています。

[RGB のデフォルト - JPEG と ICC
プロファイル](https://blog.awm.jp/2016/09/10/jpegicc/#rgb-%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88)

> Web の世界では sRGB が標準です。  
>  ICC プロファイルが入っていない JPEG 画像は sRGB として暗黙的に解釈します。(少なくとも Safari では)

ICC プロファイルが入っていないものもあると示されています。

* * *

  * **javascriptでjpgファイルからICC_PROFILEを消すにはどうすればよいでしょうか？**

出来るかどうか不明ですが、例えばこちらの記事で説明されているChromeブラウザの`Force color
profile`を切り替えて試してみてはどうでしょう？  
[｜ﾛlll)ウェブブラウザーで画像がキレイに表示されない→解決
d(･_｜](https://sorairocamera.net/2018/09/30/1111/)

関連/影響があるかどうかわかりませんが、その近くに`Forced Colors`というのもあるようです。  
[Chromeの色がおかしくなった！色が薄い…。](https://sambunnoichi.com/chrome-01/)

存在するデータを変換したり消去したりするよりも、サポートしているツールに切り替えた方が良いのでは？  
[WindowsのフォトビューアーはICCプロファイルv4に未対応…Honeyviewを導入
](https://yphoto720.blog.fc2.com/blog-entry-4797.html)  
[Honeyview](https://www.bandisoft.com/honeyview/)

> ライセンス: フリーウェア(アドウェア/スパイウェア/ウイルスなし),
> [EULA](https://www.bandisoft.com/honeyview/eula/)

こちらはWindows10で表示は出来るものの、色が違う際の対処らしいです。  
[Windows10のフォトビューワーの色がおかしいよ](https://vertys.net/photo-viewer-color-management-
for-windows10/)

こちらは古くて解決していないですが、同様の質問記事です。  
[ICCプロファイルを含むJPEGを、含まないJPEGに変換したい](https://teratail.com/questions/16063)

* * *

どうしても削除したい場合は、exiftool で出来るかもしれません。  
こちらは承認されていませんが。  
[How do i remove embedded color profile from jpg
image?](https://stackoverflow.com/q/26111530/9014308)

オプション1つでは駄目で組み合わせが必要なようです。  
ただしこれで解決した印もありませんが。  
[Topic: How to remove ICC Profile -icc_profile:all= does not seem to work
(Read 8517 times)](https://exiftool.org/forum/index.php?topic=3979.0)

> It seems that if there is no actual profile embedded PS interprets the
> Colorspace property and treats the image as if there were an embedded
> profile.  
>  So I need to remove the Colorspace property, too. Adding "-all:Colorspace="
> to what I'm doing solves my problem.

JavaScriptから何かするには、こんなツールがあるようなので、使えるかもしれません。  
[node-exiftool](https://www.npmjs.com/package/node-exiftool)

> A Node.js interface to the exiftool command-line application.

* * *

逆にこちらは color profile 以外のメタデータを削除したい質問ですが、color profileを削除すると色が変わるからのようです。  
[How can I strip tags from a JPEG without removing the color
profile?](https://photo.stackexchange.com/q/56378)  
後から付いた回答で、単純に削除するのはお勧めしない、管理ソフトを使って正しいフォーマットに変換した方が良いと書かれています。

そしてこちらの記事では、ICC_PROFILEのデータは多くの場所に組み込まれているので、それを整合性を保って取り除くのは大変らしく書いてあるようです。  
[JPG - how to read / extract data from ICC profile section
APP2](https://stackoverflow.com/q/61758329/9014308)


CC BY-SA 4.0
2021-05-28T16:06:49.097
76159
2021-05-28T16:54:19.180
2021-05-28T16:54:19.180
26370
26370
76156
answer


>
> puppeteerでscreenshotを作成した時点ではICC_PROFILEありで、それをjavascript上でICC_PROFILEなしのjpgに変換する

[rsms/node-imagemagick: Imagemagick module for
NodeJS](https://github.com/rsms/node-imagemagick) を使う方法があります。

**Install**

[code]

    $ npm i imagemagick
    
[/code]

**Code**

Imagemagick の convert コマンドで `convert ss.jpg +profile icc ...` を実行すると ICC
profile データを削除します。

[code]

    const puppeteer = require('puppeteer');
    const im = require('imagemagick');
    
    (async () => {
      browser = await puppeteer.launch({ headless: false });
      const page = await browser.newPage();
      const url = 'https://www.google.com';
      await page.goto(url, { waitUntil: 'networkidle0' });
      await page.screenshot({ type: 'jpeg', path: 'ss.jpg' });
      await browser.close();
    
      im.convert('ss.jpg +profile icc ss_remove_icc_profile.jpg'.split(' '), (err)=> {
        if (err) throw err;
        console.log('remove icc profile data')
      })
    })();
    
[/code]


CC BY-SA 4.0
2021-05-28T18:41:21.770
76162
2021-05-28T18:41:21.770
76156
answer


metropolisさんの回答を参考にsharpモジュールを使うことで解決しました。

[code]

    const sharp = require('sharp')
    中略
    const image = await page.screenshot({ type: 'jpeg'});
    await sharp(image).toFile('ss.jpg')
    
[/code]

・puppeteerでjpgの生成、ファイルの保存  
をしていたところを  
・puppetterでjpgの生成、バッファーへ一旦格納  
・sharpでファイルの保存  
としたらICC_PROFILEを含まない画像として保存できました。


CC BY-SA 4.0
2021-05-29T01:59:05.563
76167
2021-05-29T01:59:05.563
45540
76156
answer