Support scale factor to buffer APIs
This commit is contained in:
		
					parent
					
						
							
								e4ead6d018
							
						
					
				
			
			
				commit
				
					
						82a81bb26e
					
				
			
		
					 3 changed files with 79 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -230,28 +230,46 @@ HICON NativeImage::GetHICON(int size) {
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
v8::Local<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
 | 
			
		||||
  scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
 | 
			
		||||
  if (IsEmpty() || png->size() > 0) {
 | 
			
		||||
    const char* data = reinterpret_cast<const char*>(png->front());
 | 
			
		||||
    const size_t length = static_cast<size_t>(png->size());
 | 
			
		||||
    return node::Buffer::Copy(isolate, data, length).ToLocalChecked();
 | 
			
		||||
  } else {
 | 
			
		||||
    std::vector<unsigned char> encoded;
 | 
			
		||||
    gfx::PNGCodec::EncodeBGRASkBitmap(image_.AsBitmap(), false, &encoded);
 | 
			
		||||
    const char* data = reinterpret_cast<char*>(encoded.data());
 | 
			
		||||
    return node::Buffer::Copy(isolate, data, encoded.size()).ToLocalChecked();
 | 
			
		||||
v8::Local<v8::Value> NativeImage::ToPNG(mate::Arguments* args) {
 | 
			
		||||
  float scale_factor = 1.0f;
 | 
			
		||||
  mate::Dictionary options;
 | 
			
		||||
  if (args->GetNext(&options))
 | 
			
		||||
    options.Get("scaleFactor", &scale_factor);
 | 
			
		||||
 | 
			
		||||
  if (scale_factor == 1.0f) {
 | 
			
		||||
    // Use raw 1x PNG bytes when available
 | 
			
		||||
    scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
 | 
			
		||||
    if (png->size() > 0) {
 | 
			
		||||
      const char* data = reinterpret_cast<const char*>(png->front());
 | 
			
		||||
      size_t size = png->size();
 | 
			
		||||
      return node::Buffer::Copy(args->isolate(), data, size).ToLocalChecked();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const SkBitmap bitmap =
 | 
			
		||||
      image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap();
 | 
			
		||||
  std::unique_ptr<std::vector<unsigned char>> encoded(
 | 
			
		||||
      new std::vector<unsigned char>());
 | 
			
		||||
  gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, encoded.get());
 | 
			
		||||
  const char* data = reinterpret_cast<char*>(encoded->data());
 | 
			
		||||
  size_t size = encoded->size();
 | 
			
		||||
  return node::Buffer::Copy(args->isolate(), data, size).ToLocalChecked();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v8::Local<v8::Value> NativeImage::ToBitmap(v8::Isolate* isolate) {
 | 
			
		||||
  if (IsEmpty()) return node::Buffer::New(isolate, 0).ToLocalChecked();
 | 
			
		||||
v8::Local<v8::Value> NativeImage::ToBitmap(mate::Arguments* args) {
 | 
			
		||||
  float scale_factor = 1.0f;
 | 
			
		||||
  mate::Dictionary options;
 | 
			
		||||
  if (args->GetNext(&options))
 | 
			
		||||
    options.Get("scaleFactor", &scale_factor);
 | 
			
		||||
 | 
			
		||||
  const SkBitmap* bitmap = image_.ToSkBitmap();
 | 
			
		||||
  SkPixelRef* ref = bitmap->pixelRef();
 | 
			
		||||
  return node::Buffer::Copy(isolate,
 | 
			
		||||
  const SkBitmap bitmap =
 | 
			
		||||
      image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap();
 | 
			
		||||
  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->getSafeSize()).ToLocalChecked();
 | 
			
		||||
                            bitmap.getSafeSize()).ToLocalChecked();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v8::Local<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
 | 
			
		||||
| 
						 | 
				
			
			@ -260,25 +278,40 @@ v8::Local<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
 | 
			
		|||
  return node::Buffer::Copy(
 | 
			
		||||
      isolate,
 | 
			
		||||
      reinterpret_cast<const char*>(&output.front()),
 | 
			
		||||
      static_cast<size_t>(output.size())).ToLocalChecked();
 | 
			
		||||
      output.size()).ToLocalChecked();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string NativeImage::ToDataURL() {
 | 
			
		||||
  scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
 | 
			
		||||
  if (IsEmpty() || png->size() > 0)
 | 
			
		||||
    return webui::GetPngDataUrl(png->front(), png->size());
 | 
			
		||||
  else
 | 
			
		||||
    return webui::GetBitmapDataUrl(image_.AsBitmap());
 | 
			
		||||
std::string NativeImage::ToDataURL(mate::Arguments* args) {
 | 
			
		||||
  float scale_factor = 1.0f;
 | 
			
		||||
  mate::Dictionary options;
 | 
			
		||||
  if (args->GetNext(&options))
 | 
			
		||||
    options.Get("scaleFactor", &scale_factor);
 | 
			
		||||
 | 
			
		||||
  if (scale_factor == 1.0f) {
 | 
			
		||||
    // Use raw 1x PNG bytes when available
 | 
			
		||||
    scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
 | 
			
		||||
    if (png->size() > 0)
 | 
			
		||||
      return webui::GetPngDataUrl(png->front(), png->size());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return webui::GetBitmapDataUrl(
 | 
			
		||||
      image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v8::Local<v8::Value> NativeImage::GetBitmap(v8::Isolate* isolate) {
 | 
			
		||||
  if (IsEmpty()) return node::Buffer::New(isolate, 0).ToLocalChecked();
 | 
			
		||||
v8::Local<v8::Value> NativeImage::GetBitmap(mate::Arguments* args) {
 | 
			
		||||
  float scale_factor = 1.0f;
 | 
			
		||||
  mate::Dictionary options;
 | 
			
		||||
  if (args->GetNext(&options))
 | 
			
		||||
    options.Get("scaleFactor", &scale_factor);
 | 
			
		||||
 | 
			
		||||
  const SkBitmap* bitmap = image_.ToSkBitmap();
 | 
			
		||||
  SkPixelRef* ref = bitmap->pixelRef();
 | 
			
		||||
  return node::Buffer::New(isolate,
 | 
			
		||||
  const SkBitmap bitmap =
 | 
			
		||||
      image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap();
 | 
			
		||||
  SkPixelRef* ref = bitmap.pixelRef();
 | 
			
		||||
  if (!ref)
 | 
			
		||||
    return node::Buffer::New(args->isolate(), 0).ToLocalChecked();
 | 
			
		||||
  return node::Buffer::New(args->isolate(),
 | 
			
		||||
                           reinterpret_cast<char*>(ref->pixels()),
 | 
			
		||||
                           bitmap->getSafeSize(),
 | 
			
		||||
                           bitmap.getSafeSize(),
 | 
			
		||||
                           &Noop,
 | 
			
		||||
                           nullptr).ToLocalChecked();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,10 +70,10 @@ class NativeImage : public mate::Wrappable<NativeImage> {
 | 
			
		|||
  ~NativeImage() override;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  v8::Local<v8::Value> ToPNG(v8::Isolate* isolate);
 | 
			
		||||
  v8::Local<v8::Value> ToPNG(mate::Arguments* args);
 | 
			
		||||
  v8::Local<v8::Value> ToJPEG(v8::Isolate* isolate, int quality);
 | 
			
		||||
  v8::Local<v8::Value> ToBitmap(v8::Isolate* isolate);
 | 
			
		||||
  v8::Local<v8::Value> GetBitmap(v8::Isolate* isolate);
 | 
			
		||||
  v8::Local<v8::Value> ToBitmap(mate::Arguments* args);
 | 
			
		||||
  v8::Local<v8::Value> GetBitmap(mate::Arguments* args);
 | 
			
		||||
  v8::Local<v8::Value> GetNativeHandle(
 | 
			
		||||
    v8::Isolate* isolate,
 | 
			
		||||
    mate::Arguments* args);
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ class NativeImage : public mate::Wrappable<NativeImage> {
 | 
			
		|||
                                   const base::DictionaryValue& options);
 | 
			
		||||
  mate::Handle<NativeImage> Crop(v8::Isolate* isolate,
 | 
			
		||||
                                 const gfx::Rect& rect);
 | 
			
		||||
  std::string ToDataURL();
 | 
			
		||||
  std::string ToDataURL(mate::Arguments* args);
 | 
			
		||||
  bool IsEmpty();
 | 
			
		||||
  gfx::Size GetSize();
 | 
			
		||||
  float GetAspectRatio();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,11 +11,15 @@ describe('nativeImage module', () => {
 | 
			
		|||
      assert.equal(empty.isEmpty(), true)
 | 
			
		||||
      assert.equal(empty.getAspectRatio(), 1)
 | 
			
		||||
      assert.equal(empty.toDataURL(), 'data:image/png;base64,')
 | 
			
		||||
      assert.equal(empty.toDataURL({scaleFactor: 2.0}), 'data:image/png;base64,')
 | 
			
		||||
      assert.deepEqual(empty.getSize(), {width: 0, height: 0})
 | 
			
		||||
      assert.deepEqual(empty.getBitmap(), [])
 | 
			
		||||
      assert.deepEqual(empty.getBitmap({scaleFactor: 2.0}), [])
 | 
			
		||||
      assert.deepEqual(empty.toBitmap(), [])
 | 
			
		||||
      assert.deepEqual(empty.toBitmap({scaleFactor: 2.0}), [])
 | 
			
		||||
      assert.deepEqual(empty.toJPEG(100), [])
 | 
			
		||||
      assert.deepEqual(empty.toPNG(), [])
 | 
			
		||||
      assert.deepEqual(empty.toPNG({scaleFactor: 2.0}), [])
 | 
			
		||||
 | 
			
		||||
      if (process.platform === 'darwin') {
 | 
			
		||||
        assert.deepEqual(empty.getNativeHandle(), [])
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +102,14 @@ describe('nativeImage module', () => {
 | 
			
		|||
      assert.deepEqual(imageC.getSize(), {width: 538, height: 190})
 | 
			
		||||
      assert(imageB.toBitmap().equals(imageC.toBitmap()))
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('supports a scale factor', () => {
 | 
			
		||||
      const imageA = nativeImage.createFromPath(path.join(__dirname, 'fixtures', 'assets', 'logo.png'))
 | 
			
		||||
      const imageB = nativeImage.createFromDataURL(imageA.toDataURL({scaleFactor: 1.0}))
 | 
			
		||||
      assert.deepEqual(imageB.getSize(), {width: 538, height: 190})
 | 
			
		||||
      const imageC = nativeImage.createFromDataURL(imageA.toDataURL({scaleFactor: 2.0}))
 | 
			
		||||
      assert.deepEqual(imageC.getSize(), {width: 538, height: 190})
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  describe('toPNG()', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue