From 17b70670f8ea78a19c193b9db84cf04c5d11c3bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Mar 2017 13:47:31 -0800 Subject: [PATCH 1/7] Add initial NativeImage.addRepresentation specs --- spec/api-native-image-spec.js | 27 +++++++++++++++++++++++++++ spec/fixtures/assets/2x2.jpg | Bin 0 -> 3176 bytes spec/fixtures/assets/3x3.png | Bin 0 -> 507 bytes 3 files changed, 27 insertions(+) create mode 100644 spec/fixtures/assets/2x2.jpg create mode 100644 spec/fixtures/assets/3x3.png diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 22fe187b2d74..d9fb31a81ecb 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -249,4 +249,31 @@ describe('nativeImage module', () => { assert.equal(nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', 'logo.png')).getAspectRatio(), 2.8315789699554443) }) }) + + describe('addRepresentation()', () => { + it('supports adding a representation for a scale factor', () => { + const image = nativeImage.createEmpty() + image.addRepresentation({ + scaleFactor: 1.0, + buffer: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '1x1.png')).toPNG() + }) + image.addRepresentation({ + scaleFactor: 2.0, + buffer: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '2x2.jpg')).toPNG() + }) + image.addRepresentation({ + scaleFactor: 3.0, + buffer: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '3x3.png')).toPNG() + }) + image.addRepresentation({ + scaleFactor: 4.0, + buffer: 'invalid' + }) + + assert.equal(image.toDataURL({scaleFactor: 1.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYlWNgAAIAAAUAAdafFs0AAAAASUVORK5CYII=') + assert.equal(image.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQYlWP8////fwYGBgYmBigAAD34BABBrq9BAAAAAElFTkSuQmCC') + assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') + assert.equal(image.toDataURL({scaleFactor: 4.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') + }) + }) }) diff --git a/spec/fixtures/assets/2x2.jpg b/spec/fixtures/assets/2x2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d96fdb313314c5f328e461727e7a992cdb6474a8 GIT binary patch literal 3176 zcmeHJSxgf_82)Du+M*;B0k0UB1r$x_mI6u}3*i(FinqSu4aP*gH5$bejb@!)YDs)DzS?g#GvDs~$9(_n!!O^LA3=!5f@H11H&iT!z8O!K^&VXLr`~ zBIDreJYFmN?(8|1@wlw)!fcz-<}2jgp3)XSU)3^ap0lOiX?C%Bxy&rdA~pCLc+t*C z4NJTMi)3Zh;1N0*=**FCeCC^#}?^AX0%y1tJxQR3K7;NCp1C3XF6+ycf4PLEOuL{1$R5+=3_s+=7qEG#DYL zpv*=o4H$;XQ&k#!ds2JfM(Czqtp9sX8bbmG`?<0qs}nVL3jdRF#~nK@=lVNr3(?9#IGs(JGlEUaEs<8<-0b#Bk% zfY`J&C^fgNTD@lNy7e2{Hf`Rrb=&sN9XogL*}HH5frEz*cON}={KUyqr_Wrtc1%j$KE3bjg{O?-LyU-sr@Xtbx=)MVhMY z?}WAfld`a|5nT_U5C|0{fp3W<@l8<}w1!ro(P~s^Lx@%}NP!fMCu_Ae*W0qmPX2bzW}+TK9c|d literal 0 HcmV?d00001 diff --git a/spec/fixtures/assets/3x3.png b/spec/fixtures/assets/3x3.png new file mode 100644 index 0000000000000000000000000000000000000000..b1c1d9d688c59194fbad1431f6c2fffc7eaa1bf1 GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z%2~Ij105p zNH8!kMrMXYltlRYSS9D@>LsS+C#C9DVstT4fPE4;bsH1+JHo@{EISEfi{E8 zw==W>t3(ll+GC>+vK+}V5TAlYfnK%aveAbJn;nB3GS( TF(Rpo5fsFpu6{1-oD!M Date: Tue, 7 Mar 2017 13:48:12 -0800 Subject: [PATCH 2/7] Add addRepresentation buffer support --- atom/common/api/atom_api_native_image.cc | 25 +++++++++++++++++++++++- atom/common/api/atom_api_native_image.h | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 98eac6b2ff68..e30b407e9ef0 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -15,7 +15,6 @@ #include "base/files/file_util.h" #include "base/strings/pattern.h" #include "base/strings/string_util.h" -#include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/base/data_url.h" #include "third_party/skia/include/core/SkPixelRef.h" @@ -387,6 +386,29 @@ mate::Handle NativeImage::Crop(v8::Isolate* isolate, new NativeImage(isolate, gfx::Image(cropped))); } +void NativeImage::AddRepresentation(const mate::Dictionary& options) { + int width = 0; + int height = 0; + float scale_factor = 1.0f; + options.Get("width", &width); + options.Get("height", &height); + options.Get("scaleFactor", &scale_factor); + + v8::Local buffer; + if (options.Get("buffer", &buffer) && node::Buffer::HasInstance(buffer)) { + gfx::ImageSkia image_skia = image_.AsImageSkia(); + AddImageSkiaRep( + &image_skia, + reinterpret_cast(node::Buffer::Data(buffer)), + node::Buffer::Length(buffer), + width, height, scale_factor); + + if (IsEmpty()) { + gfx::Image image(image_skia); + image_.SwapRepresentations(&image); + } + } +} #if !defined(OS_MACOSX) void NativeImage::SetTemplateImage(bool setAsTemplate) { @@ -504,6 +526,7 @@ void NativeImage::BuildPrototype( .SetMethod("resize", &NativeImage::Resize) .SetMethod("crop", &NativeImage::Crop) .SetMethod("getAspectRatio", &NativeImage::GetAspectRatio) + .SetMethod("addRepresentation", &NativeImage::AddRepresentation) // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG); diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index a6614a81b0ec..6ff7a0e29f37 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -9,6 +9,7 @@ #include #include "base/values.h" +#include "native_mate/dictionary.h" #include "native_mate/handle.h" #include "native_mate/wrappable.h" #include "ui/gfx/geometry/rect.h" @@ -85,6 +86,7 @@ class NativeImage : public mate::Wrappable { bool IsEmpty(); gfx::Size GetSize(); float GetAspectRatio(); + void AddRepresentation(const mate::Dictionary& options); // Mark the image as template image. void SetTemplateImage(bool setAsTemplate); From 7e039d92ec4fb02804f4fc3afed8c1c80e99ab9f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Mar 2017 14:24:37 -0800 Subject: [PATCH 3/7] Support adding representation from data URL --- atom/common/api/atom_api_native_image.cc | 27 +++++++++++++++++++----- spec/api-native-image-spec.js | 27 +++++++++++++++++++++++- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index e30b407e9ef0..6811ab919303 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -394,20 +394,37 @@ void NativeImage::AddRepresentation(const mate::Dictionary& options) { options.Get("height", &height); options.Get("scaleFactor", &scale_factor); + bool skia_rep_added = false; + gfx::ImageSkia image_skia = image_.AsImageSkia(); + v8::Local buffer; + GURL url; if (options.Get("buffer", &buffer) && node::Buffer::HasInstance(buffer)) { - gfx::ImageSkia image_skia = image_.AsImageSkia(); AddImageSkiaRep( &image_skia, reinterpret_cast(node::Buffer::Data(buffer)), node::Buffer::Length(buffer), width, height, scale_factor); - - if (IsEmpty()) { - gfx::Image image(image_skia); - image_.SwapRepresentations(&image); + skia_rep_added = true; + } else if (options.Get("dataURL", &url)) { + std::string mime_type, charset, data; + if (net::DataURL::Parse(url, &mime_type, &charset, &data)) { + if (mime_type == "image/png" || mime_type == "image/jpeg") { + AddImageSkiaRep( + &image_skia, + reinterpret_cast(data.c_str()), + data.size(), + width, height, scale_factor); + skia_rep_added = true; + } } } + + // Re-initialize image when first representation is added to an empty image + if (skia_rep_added && IsEmpty()) { + gfx::Image image(image_skia); + image_.SwapRepresentations(&image); + } } #if !defined(OS_MACOSX) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index d9fb31a81ecb..af90332e5acb 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -251,7 +251,7 @@ describe('nativeImage module', () => { }) describe('addRepresentation()', () => { - it('supports adding a representation for a scale factor', () => { + it('supports adding a buffer representation for a scale factor', () => { const image = nativeImage.createEmpty() image.addRepresentation({ scaleFactor: 1.0, @@ -275,5 +275,30 @@ describe('nativeImage module', () => { assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') assert.equal(image.toDataURL({scaleFactor: 4.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') }) + + it('supports adding a data URL representation for a scale factor', () => { + const image = nativeImage.createEmpty() + image.addRepresentation({ + scaleFactor: 1.0, + dataURL: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '1x1.png')).toDataURL() + }) + image.addRepresentation({ + scaleFactor: 2.0, + dataURL: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '2x2.jpg')).toDataURL() + }) + image.addRepresentation({ + scaleFactor: 3.0, + dataURL: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '3x3.png')).toDataURL() + }) + image.addRepresentation({ + scaleFactor: 4.0, + dataURL: 'invalid' + }) + + assert.equal(image.toDataURL({scaleFactor: 1.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYlWNgAAIAAAUAAdafFs0AAAAASUVORK5CYII=') + assert.equal(image.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQYlWP8////fwYGBgYmBigAAD34BABBrq9BAAAAAElFTkSuQmCC') + assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') + assert.equal(image.toDataURL({scaleFactor: 4.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') + }) }) }) From 6e977cbc3abe9ee8c3233ac8bcadefd78c78371a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Mar 2017 14:26:31 -0800 Subject: [PATCH 4/7] Assert emptiness and size of built up images --- spec/api-native-image-spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index af90332e5acb..206a18044109 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -270,6 +270,8 @@ describe('nativeImage module', () => { buffer: 'invalid' }) + assert.equal(image.isEmpty(), false) + assert.deepEqual(image.getSize(), {width: 1, height: 1}) assert.equal(image.toDataURL({scaleFactor: 1.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYlWNgAAIAAAUAAdafFs0AAAAASUVORK5CYII=') assert.equal(image.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQYlWP8////fwYGBgYmBigAAD34BABBrq9BAAAAAElFTkSuQmCC') assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') @@ -295,6 +297,8 @@ describe('nativeImage module', () => { dataURL: 'invalid' }) + assert.equal(image.isEmpty(), false) + assert.deepEqual(image.getSize(), {width: 1, height: 1}) assert.equal(image.toDataURL({scaleFactor: 1.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYlWNgAAIAAAUAAdafFs0AAAAASUVORK5CYII=') assert.equal(image.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQYlWP8////fwYGBgYmBigAAD34BABBrq9BAAAAAElFTkSuQmCC') assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') From 089bfd2cd2e24e5bb85e0a89c0bdf67b78c5f242 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Mar 2017 14:29:37 -0800 Subject: [PATCH 5/7] Document nativeImage.addRepresentation(options) --- docs/api/native-image.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 0350f13bc902..69658d6f87b5 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -265,4 +265,18 @@ will be preserved in the resized image. Returns `Float` - The image's aspect ratio. +#### `image.addRepresentation(options)` + +* `options` Object + * `scaleFactor` Double - The scale factor to add the image representation for. + * `width` Integer (optional) + * `height` Integer (optional) + * `buffer` Buffer (optional) - The buffer containing the raw image data. + * `dataURL` String (optional) - The data URL containing either a base 64 + encoded PNG or JPEG image. + +Add an image representation for a specific scale factor. This can be used +to explicitly add different scale factor representations to an image. This +can be called on empty images. + [buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer From 2946f624ac3fc0fa7bd4cfe288765c645110cd65 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Mar 2017 14:53:08 -0800 Subject: [PATCH 6/7] Add spec for adding representation to existing image --- spec/api-native-image-spec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 206a18044109..9b8e5c3a2e01 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -304,5 +304,20 @@ describe('nativeImage module', () => { assert.equal(image.toDataURL({scaleFactor: 3.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') assert.equal(image.toDataURL({scaleFactor: 4.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAADElEQVQYlWNgIAoAAAAnAAGZWEMnAAAAAElFTkSuQmCC') }) + + it('supports adding a representation to an existing image', () => { + const image = nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '1x1.png')) + image.addRepresentation({ + scaleFactor: 2.0, + dataURL: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '2x2.jpg')).toDataURL() + }) + image.addRepresentation({ + scaleFactor: 2.0, + dataURL: nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', '3x3.png')).toDataURL() + }) + + assert.equal(image.toDataURL({scaleFactor: 1.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYlWNgAAIAAAUAAdafFs0AAAAASUVORK5CYII=') + assert.equal(image.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQYlWP8////fwYGBgYmBigAAD34BABBrq9BAAAAAElFTkSuQmCC') + }) }) }) From f19998ef4c7ac77aa55e4f2cc5e30fe97fa9de14 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Mar 2017 10:12:03 -0800 Subject: [PATCH 7/7] Add more default values --- docs/api/native-image.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 69658d6f87b5..100fb0e1a222 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -247,8 +247,8 @@ Returns `NativeImage` - The cropped image. #### `image.resize(options)` * `options` Object - * `width` Integer (optional) - * `height` Integer (optional) + * `width` Integer (optional) - Defaults to the image's width. + * `height` Integer (optional) - Defaults to the image's height * `quality` String (optional) - The desired quality of the resize image. Possible values are `good`, `better` or `best`. The default is `best`. These values express a desired quality/speed tradeoff. They are translated @@ -269,8 +269,10 @@ Returns `Float` - The image's aspect ratio. * `options` Object * `scaleFactor` Double - The scale factor to add the image representation for. - * `width` Integer (optional) - * `height` Integer (optional) + * `width` Integer (optional) - Defaults to 0. Required if a bitmap buffer + is specified as `buffer`. + * `height` Integer (optional) - Defaults to 0. Required if a bitmap buffer + is specified as `buffer`. * `buffer` Buffer (optional) - The buffer containing the raw image data. * `dataURL` String (optional) - The data URL containing either a base 64 encoded PNG or JPEG image.