{"action":"created","comment":{"url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/comments/211011671","pull_request_review_id":147352124,"id":211011671,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxMTAxMTY3MQ==","diff_hunk":"@@ -0,0 +1,95 @@\n+/**\n+ * Copyright 2017 The AMP HTML Authors. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS-IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+'use strict';\n+const sizeOf = require('image-size');\n+const jimp = require('jimp');\n+\n+/**\n+ * Adds placeholders for all AMP images and posters that are blurry versions of\n+ * the corresponding original source. The blur will be displayed as the\n+ * <amp-img> is rendering, and will fade out once the element is loaded.\n+ */\n+\n+class BlurImagePlaceholders {\n+\n+  transform(tree, params) {\n+    const html = tree.root.firstChildByTag('html');\n+    const body = html.firstChildByTag('body');\n+    let node = body;\n+    const ampImgPromises = [];\n+    while (node !== null) {\n+      if (node.tagName === 'amp-img' ||\n+      (node.tagName === 'amp-video' && node.attribs.poster)) {\n+        let parent = node;\n+        ampImgPromises.push(this.addBitmap_(tree, parent).then(imgChild => {\n+          parent.appendChild(imgChild);\n+          console.log(imgChild.attribs.src);\n+        }));\n+      }\n+      node = node.nextNode();\n+    }\n+    return Promise.all(ampImgPromises);\n+  }\n+\n+  addBitmap_(tree, node) {\n+    const imgChild = tree.createElement('img');\n+    if (node.tagName === 'amp-img') {\n+      imgChild.attribs.src = node.attribs.src;\n+    } else {\n+      imgChild.attribs.src = node.attribs.poster;\n+    }\n+    imgChild.attribs.class = 'i-amphtml-blur';\n+    imgChild.attribs.placeholder = '';\n+    return this.getDataURI_(imgChild, tree).then(() => {\n+      return imgChild;\n+    });\n+  }\n+\n+  getDataURI_(node, tree) {\n+    const bitMapDims = this.getBitmapDimensions_(node, tree);\n+    return this.createBitmap_(node, bitMapDims[0], bitMapDims[1]).then(dataURI => {\n+      node.attribs.src = dataURI;\n+    });\n+  }\n+\n+  getBitmapDimensions_(node, tree) {\n+    const imgDims = sizeOf(node.attribs.src);\n+    const bitmapPixelAmt = 60;\n+    const tempImg = tree.createElement('IMG');\n+    tempImg.attribs.src = node.attribs.src;\n+    const imgWidth = imgDims.width;\n+    const imgHeight = imgDims.height;\n+    const ratioWidth = imgWidth / imgHeight;\n+    let bitmapHeight = bitmapPixelAmt / ratioWidth;\n+    bitmapHeight = Math.sqrt(bitmapHeight);\n+    const bitmapWidth = bitmapPixelAmt / bitmapHeight;\n+    return [Math.round(bitmapWidth), Math.round(bitmapHeight)];\n+  }\n+\n+  createBitmap_(node, width, height) {\n+    return jimp.read(node.attribs.src)\n+    .then(image => {\n+      image.resize(width, height, jimp.RESIZE_BEZIER);\n+      return image.getBase64Async('image/png');","path":"optimizer/lib/transformers/BlurImagePlaceholders.js","position":86,"original_position":86,"commit_id":"6881c0638c4ec89e5de9ecc3f71ff56e55d3d65f","original_commit_id":"6881c0638c4ec89e5de9ecc3f71ff56e55d3d65f","user":{"login":"choumx","id":20525523,"node_id":"MDQ6VXNlcjIwNTI1NTIz","avatar_url":"https://avatars1.githubusercontent.com/u/20525523?v=4","gravatar_id":"","url":"https://api.github.com/users/choumx","html_url":"https://github.com/choumx","followers_url":"https://api.github.com/users/choumx/followers","following_url":"https://api.github.com/users/choumx/following{/other_user}","gists_url":"https://api.github.com/users/choumx/gists{/gist_id}","starred_url":"https://api.github.com/users/choumx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/choumx/subscriptions","organizations_url":"https://api.github.com/users/choumx/orgs","repos_url":"https://api.github.com/users/choumx/repos","events_url":"https://api.github.com/users/choumx/events{/privacy}","received_events_url":"https://api.github.com/users/choumx/received_events","type":"User","site_admin":false},"body":"How is the size of these data URIs compared to GIFs?","created_at":"2018-08-17T19:31:06Z","updated_at":"2018-08-17T19:31:17Z","html_url":"https://github.com/ampproject/amp-toolbox/pull/78#discussion_r211011671","pull_request_url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/comments/211011671"},"html":{"href":"https://github.com/ampproject/amp-toolbox/pull/78#discussion_r211011671"},"pull_request":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78"}}},"pull_request":{"url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78","id":208086471,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA4MDg2NDcx","html_url":"https://github.com/ampproject/amp-toolbox/pull/78","diff_url":"https://github.com/ampproject/amp-toolbox/pull/78.diff","patch_url":"https://github.com/ampproject/amp-toolbox/pull/78.patch","issue_url":"https://api.github.com/repos/ampproject/amp-toolbox/issues/78","number":78,"state":"open","locked":false,"title":"Implements optimizer transformer that adds blurry placeholders to images","user":{"login":"addieachan","id":39060570,"node_id":"MDQ6VXNlcjM5MDYwNTcw","avatar_url":"https://avatars0.githubusercontent.com/u/39060570?v=4","gravatar_id":"","url":"https://api.github.com/users/addieachan","html_url":"https://github.com/addieachan","followers_url":"https://api.github.com/users/addieachan/followers","following_url":"https://api.github.com/users/addieachan/following{/other_user}","gists_url":"https://api.github.com/users/addieachan/gists{/gist_id}","starred_url":"https://api.github.com/users/addieachan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/addieachan/subscriptions","organizations_url":"https://api.github.com/users/addieachan/orgs","repos_url":"https://api.github.com/users/addieachan/repos","events_url":"https://api.github.com/users/addieachan/events{/privacy}","received_events_url":"https://api.github.com/users/addieachan/received_events","type":"User","site_admin":false},"body":"- Addresses issue https://github.com/ampproject/amphtml/issues/15146\r\n- Currently blurs all <amp-img> tags and <amp-video> tags with a poster attribute.","created_at":"2018-08-13T19:59:29Z","updated_at":"2018-08-17T19:31:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d6f515bfe012d7f50ad794ca412c012d0a78e9fc","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78/commits","review_comments_url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78/comments","review_comment_url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ampproject/amp-toolbox/issues/78/comments","statuses_url":"https://api.github.com/repos/ampproject/amp-toolbox/statuses/6881c0638c4ec89e5de9ecc3f71ff56e55d3d65f","head":{"label":"addieachan:patch-1","ref":"patch-1","sha":"6881c0638c4ec89e5de9ecc3f71ff56e55d3d65f","user":{"login":"addieachan","id":39060570,"node_id":"MDQ6VXNlcjM5MDYwNTcw","avatar_url":"https://avatars0.githubusercontent.com/u/39060570?v=4","gravatar_id":"","url":"https://api.github.com/users/addieachan","html_url":"https://github.com/addieachan","followers_url":"https://api.github.com/users/addieachan/followers","following_url":"https://api.github.com/users/addieachan/following{/other_user}","gists_url":"https://api.github.com/users/addieachan/gists{/gist_id}","starred_url":"https://api.github.com/users/addieachan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/addieachan/subscriptions","organizations_url":"https://api.github.com/users/addieachan/orgs","repos_url":"https://api.github.com/users/addieachan/repos","events_url":"https://api.github.com/users/addieachan/events{/privacy}","received_events_url":"https://api.github.com/users/addieachan/received_events","type":"User","site_admin":false},"repo":{"id":143327434,"node_id":"MDEwOlJlcG9zaXRvcnkxNDMzMjc0MzQ=","name":"amp-toolbox","full_name":"addieachan/amp-toolbox","owner":{"login":"addieachan","id":39060570,"node_id":"MDQ6VXNlcjM5MDYwNTcw","avatar_url":"https://avatars0.githubusercontent.com/u/39060570?v=4","gravatar_id":"","url":"https://api.github.com/users/addieachan","html_url":"https://github.com/addieachan","followers_url":"https://api.github.com/users/addieachan/followers","following_url":"https://api.github.com/users/addieachan/following{/other_user}","gists_url":"https://api.github.com/users/addieachan/gists{/gist_id}","starred_url":"https://api.github.com/users/addieachan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/addieachan/subscriptions","organizations_url":"https://api.github.com/users/addieachan/orgs","repos_url":"https://api.github.com/users/addieachan/repos","events_url":"https://api.github.com/users/addieachan/events{/privacy}","received_events_url":"https://api.github.com/users/addieachan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/addieachan/amp-toolbox","description":" A collection of AMP tools making it easier to publish and host AMP pages. ","fork":true,"url":"https://api.github.com/repos/addieachan/amp-toolbox","forks_url":"https://api.github.com/repos/addieachan/amp-toolbox/forks","keys_url":"https://api.github.com/repos/addieachan/amp-toolbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/addieachan/amp-toolbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/addieachan/amp-toolbox/teams","hooks_url":"https://api.github.com/repos/addieachan/amp-toolbox/hooks","issue_events_url":"https://api.github.com/repos/addieachan/amp-toolbox/issues/events{/number}","events_url":"https://api.github.com/repos/addieachan/amp-toolbox/events","assignees_url":"https://api.github.com/repos/addieachan/amp-toolbox/assignees{/user}","branches_url":"https://api.github.com/repos/addieachan/amp-toolbox/branches{/branch}","tags_url":"https://api.github.com/repos/addieachan/amp-toolbox/tags","blobs_url":"https://api.github.com/repos/addieachan/amp-toolbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/addieachan/amp-toolbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/addieachan/amp-toolbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/addieachan/amp-toolbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/addieachan/amp-toolbox/statuses/{sha}","languages_url":"https://api.github.com/repos/addieachan/amp-toolbox/languages","stargazers_url":"https://api.github.com/repos/addieachan/amp-toolbox/stargazers","contributors_url":"https://api.github.com/repos/addieachan/amp-toolbox/contributors","subscribers_url":"https://api.github.com/repos/addieachan/amp-toolbox/subscribers","subscription_url":"https://api.github.com/repos/addieachan/amp-toolbox/subscription","commits_url":"https://api.github.com/repos/addieachan/amp-toolbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/addieachan/amp-toolbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/addieachan/amp-toolbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/addieachan/amp-toolbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/addieachan/amp-toolbox/contents/{+path}","compare_url":"https://api.github.com/repos/addieachan/amp-toolbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/addieachan/amp-toolbox/merges","archive_url":"https://api.github.com/repos/addieachan/amp-toolbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/addieachan/amp-toolbox/downloads","issues_url":"https://api.github.com/repos/addieachan/amp-toolbox/issues{/number}","pulls_url":"https://api.github.com/repos/addieachan/amp-toolbox/pulls{/number}","milestones_url":"https://api.github.com/repos/addieachan/amp-toolbox/milestones{/number}","notifications_url":"https://api.github.com/repos/addieachan/amp-toolbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/addieachan/amp-toolbox/labels{/name}","releases_url":"https://api.github.com/repos/addieachan/amp-toolbox/releases{/id}","deployments_url":"https://api.github.com/repos/addieachan/amp-toolbox/deployments","created_at":"2018-08-02T17:47:23Z","updated_at":"2018-08-02T17:47:25Z","pushed_at":"2018-08-17T15:19:03Z","git_url":"git://github.com/addieachan/amp-toolbox.git","ssh_url":"git@github.com:addieachan/amp-toolbox.git","clone_url":"https://github.com/addieachan/amp-toolbox.git","svn_url":"https://github.com/addieachan/amp-toolbox","homepage":"","size":4248,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ampproject:master","ref":"master","sha":"62de968a2c9146dc85688970c68855fc1af18c27","user":{"login":"ampproject","id":14114390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTE0Mzkw","avatar_url":"https://avatars3.githubusercontent.com/u/14114390?v=4","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"repo":{"id":113579983,"node_id":"MDEwOlJlcG9zaXRvcnkxMTM1Nzk5ODM=","name":"amp-toolbox","full_name":"ampproject/amp-toolbox","owner":{"login":"ampproject","id":14114390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTE0Mzkw","avatar_url":"https://avatars3.githubusercontent.com/u/14114390?v=4","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ampproject/amp-toolbox","description":" A collection of AMP tools making it easier to publish and host AMP pages. ","fork":false,"url":"https://api.github.com/repos/ampproject/amp-toolbox","forks_url":"https://api.github.com/repos/ampproject/amp-toolbox/forks","keys_url":"https://api.github.com/repos/ampproject/amp-toolbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ampproject/amp-toolbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ampproject/amp-toolbox/teams","hooks_url":"https://api.github.com/repos/ampproject/amp-toolbox/hooks","issue_events_url":"https://api.github.com/repos/ampproject/amp-toolbox/issues/events{/number}","events_url":"https://api.github.com/repos/ampproject/amp-toolbox/events","assignees_url":"https://api.github.com/repos/ampproject/amp-toolbox/assignees{/user}","branches_url":"https://api.github.com/repos/ampproject/amp-toolbox/branches{/branch}","tags_url":"https://api.github.com/repos/ampproject/amp-toolbox/tags","blobs_url":"https://api.github.com/repos/ampproject/amp-toolbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ampproject/amp-toolbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ampproject/amp-toolbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/ampproject/amp-toolbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ampproject/amp-toolbox/statuses/{sha}","languages_url":"https://api.github.com/repos/ampproject/amp-toolbox/languages","stargazers_url":"https://api.github.com/repos/ampproject/amp-toolbox/stargazers","contributors_url":"https://api.github.com/repos/ampproject/amp-toolbox/contributors","subscribers_url":"https://api.github.com/repos/ampproject/amp-toolbox/subscribers","subscription_url":"https://api.github.com/repos/ampproject/amp-toolbox/subscription","commits_url":"https://api.github.com/repos/ampproject/amp-toolbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/ampproject/amp-toolbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/ampproject/amp-toolbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/ampproject/amp-toolbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/ampproject/amp-toolbox/contents/{+path}","compare_url":"https://api.github.com/repos/ampproject/amp-toolbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ampproject/amp-toolbox/merges","archive_url":"https://api.github.com/repos/ampproject/amp-toolbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ampproject/amp-toolbox/downloads","issues_url":"https://api.github.com/repos/ampproject/amp-toolbox/issues{/number}","pulls_url":"https://api.github.com/repos/ampproject/amp-toolbox/pulls{/number}","milestones_url":"https://api.github.com/repos/ampproject/amp-toolbox/milestones{/number}","notifications_url":"https://api.github.com/repos/ampproject/amp-toolbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ampproject/amp-toolbox/labels{/name}","releases_url":"https://api.github.com/repos/ampproject/amp-toolbox/releases{/id}","deployments_url":"https://api.github.com/repos/ampproject/amp-toolbox/deployments","created_at":"2017-12-08T13:57:07Z","updated_at":"2018-08-14T10:39:57Z","pushed_at":"2018-08-17T15:19:04Z","git_url":"git://github.com/ampproject/amp-toolbox.git","ssh_url":"git@github.com:ampproject/amp-toolbox.git","clone_url":"https://github.com/ampproject/amp-toolbox.git","svn_url":"https://github.com/ampproject/amp-toolbox","homepage":"","size":442,"stargazers_count":65,"watchers_count":65,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":27,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":27,"open_issues":12,"watchers":65,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78"},"html":{"href":"https://github.com/ampproject/amp-toolbox/pull/78"},"issue":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/issues/78"},"comments":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/issues/78/comments"},"review_comments":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78/comments"},"review_comment":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/pulls/78/commits"},"statuses":{"href":"https://api.github.com/repos/ampproject/amp-toolbox/statuses/6881c0638c4ec89e5de9ecc3f71ff56e55d3d65f"}},"author_association":"NONE"}}
{"actor":{"display_login":"choumx"}}