From 17a7db57389c3b87bca31b0d7b120d66175ff237 Mon Sep 17 00:00:00 2001 From: Jeremy Rose Date: Fri, 2 Oct 2020 16:14:04 -0700 Subject: [PATCH] fix: nativeImage.crop().toBitmap() returning garbage --- shell/common/api/electron_api_native_image.cc | 21 ++++++++++++------- spec/api-native-image-spec.js | 6 ++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/shell/common/api/electron_api_native_image.cc b/shell/common/api/electron_api_native_image.cc index cd2faa86fcb22..8159d0a062616 100644 --- a/shell/common/api/electron_api_native_image.cc +++ b/shell/common/api/electron_api_native_image.cc @@ -180,13 +180,20 @@ v8::Local NativeImage::ToBitmap(gin::Arguments* args) { const SkBitmap bitmap = image_.AsImageSkia().GetRepresentation(scale_factor).GetBitmap(); - SkPixelRef* ref = bitmap.pixelRef(); - if (!ref) - return node::Buffer::New(args->isolate(), 0).ToLocalChecked(); - return node::Buffer::Copy(args->isolate(), - reinterpret_cast(ref->pixels()), - bitmap.computeByteSize()) - .ToLocalChecked(); + + SkImageInfo info = + SkImageInfo::MakeN32Premul(bitmap.width(), bitmap.height()); + + auto array_buffer = + v8::ArrayBuffer::New(args->isolate(), info.computeMinByteSize()); + auto backing_store = array_buffer->GetBackingStore(); + if (bitmap.readPixels(info, backing_store->Data(), info.minRowBytes(), 0, + 0)) { + return node::Buffer::New(args->isolate(), array_buffer, 0, + info.computeMinByteSize()) + .ToLocalChecked(); + } + return node::Buffer::New(args->isolate(), 0).ToLocalChecked(); } v8::Local NativeImage::ToJPEG(v8::Isolate* isolate, int quality) { diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index ae5ef33de6a92..8ef1964a0289c 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -498,6 +498,12 @@ describe('nativeImage module', () => { expect(cropB.getSize()).to.deep.equal({ width: 25, height: 64 }); expect(cropA.toPNG().equals(cropB.toPNG())).to.be.false(); }); + + it('toBitmap() returns a buffer of the right size', () => { + const image = nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', 'logo.png')); + const crop = image.crop({ width: 25, height: 64, x: 0, y: 0 }); + expect(crop.toBitmap().length).to.equal(25 * 64 * 4); + }); }); describe('getAspectRatio()', () => {