Browse Source

fix: nativeImage.crop().toBitmap() returning garbage (#25757)

Jeremy Rose 4 years ago
parent
commit
485adae94c
2 changed files with 20 additions and 7 deletions
  1. 14 7
      shell/common/api/electron_api_native_image.cc
  2. 6 0
      spec/api-native-image-spec.js

+ 14 - 7
shell/common/api/electron_api_native_image.cc

@@ -183,13 +183,20 @@ v8::Local<v8::Value> 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<const char*>(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<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {

+ 6 - 0
spec/api-native-image-spec.js

@@ -468,6 +468,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()', () => {