Merge pull request #1128 from atom/native-image

Introduce NativeImage
This commit is contained in:
Cheng Zhao 2015-02-12 16:48:42 +08:00
commit 64622ceae3
20 changed files with 499 additions and 195 deletions

View file

@ -38,6 +38,7 @@
'atom/common/api/lib/clipboard.coffee',
'atom/common/api/lib/crash-reporter.coffee',
'atom/common/api/lib/id-weak-map.coffee',
'atom/common/api/lib/native-image.coffee',
'atom/common/api/lib/original-fs.coffee',
'atom/common/api/lib/shell.coffee',
'atom/common/lib/init.coffee',
@ -204,6 +205,9 @@
'atom/common/api/atom_api_crash_reporter.cc',
'atom/common/api/atom_api_id_weak_map.cc',
'atom/common/api/atom_api_id_weak_map.h',
'atom/common/api/atom_api_native_image.cc',
'atom/common/api/atom_api_native_image.h',
'atom/common/api/atom_api_native_image_mac.mm',
'atom/common/api/atom_api_shell.cc',
'atom/common/api/atom_api_v8_util.cc',
'atom/common/api/atom_bindings.cc',
@ -242,7 +246,6 @@
'atom/common/native_mate_converters/gurl_converter.h',
'atom/common/native_mate_converters/image_converter.cc',
'atom/common/native_mate_converters/image_converter.h',
'atom/common/native_mate_converters/image_converter_mac.mm',
'atom/common/native_mate_converters/string16_converter.h',
'atom/common/native_mate_converters/v8_value_converter.cc',
'atom/common/native_mate_converters/v8_value_converter.h',

View file

@ -52,15 +52,11 @@ namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(v8::Handle<v8::Value>)>& callback,
const base::Callback<void(const gfx::Image&)>& callback,
const std::vector<unsigned char>& data) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Value> buffer = node::Buffer::New(
reinterpret_cast<const char*>(data.data()),
data.size());
callback.Run(buffer);
callback.Run(gfx::Image::CreateFrom1xPNGBytes(&data.front(), data.size()));
}
} // namespace
@ -374,7 +370,7 @@ bool Window::IsDocumentEdited() {
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(v8::Handle<v8::Value>)> callback;
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)

View file

@ -54,13 +54,11 @@ TrayIconCocoa::~TrayIconCocoa() {
}
void TrayIconCocoa::SetImage(const gfx::Image& image) {
if (!image.IsEmpty())
[item_ setImage:image.ToNSImage()];
[item_ setImage:image.AsNSImage()];
}
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
if (!image.IsEmpty())
[item_ setAlternateImage:image.ToNSImage()];
[item_ setAlternateImage:image.AsNSImage()];
}
void TrayIconCocoa::SetToolTip(const std::string& tool_tip) {

View file

@ -5,10 +5,13 @@
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/dictionary.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/image/image.h"
#include "atom/common/node_includes.h"
@ -16,8 +19,7 @@ namespace mate {
template<>
struct Converter<ui::ClipboardType> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
ui::ClipboardType* out) {
std::string type;
if (!Converter<std::string>::FromV8(isolate, val, &type))
@ -62,6 +64,11 @@ void WriteText(const base::string16& text, ui::ClipboardType type) {
writer.WriteText(text);
}
gfx::Image ReadImage(ui::ClipboardType type) {
SkBitmap bitmap = ui::Clipboard::GetForCurrentThread()->ReadImage(type);
return gfx::Image::CreateFrom1xBitmap(bitmap);
}
void Clear(ui::ClipboardType type) {
ui::Clipboard::GetForCurrentThread()->Clear(type);
}
@ -73,6 +80,7 @@ void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
dict.SetMethod("_read", &Read);
dict.SetMethod("_readText", &ReadText);
dict.SetMethod("_writeText", &WriteText);
dict.SetMethod("_readImage", &ReadImage);
dict.SetMethod("_clear", &Clear);
}

View file

@ -0,0 +1,266 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/api/atom_api_native_image.h"
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/base64.h"
#include "base/files/file_util.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 "ui/base/layout.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_util.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
namespace {
struct ScaleFactorPair {
const char* name;
float scale;
};
ScaleFactorPair kScaleFactorPairs[] = {
// The "@2x" is put as first one to make scale matching faster.
{ "@2x" , 2.0f },
{ "@3x" , 3.0f },
{ "@1x" , 1.0f },
{ "@4x" , 4.0f },
{ "@5x" , 5.0f },
{ "@1.25x" , 1.25f },
{ "@1.33x" , 1.33f },
{ "@1.4x" , 1.4f },
{ "@1.5x" , 1.5f },
{ "@1.8x" , 1.8f },
{ "@2.5x" , 2.5f },
};
float GetScaleFactorFromPath(const base::FilePath& path) {
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
// We don't try to convert string to float here because it is very very
// expensive.
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
return kScaleFactorPairs[i].scale;
}
return 1.0f;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
double scale_factor) {
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (!decoded)
return false;
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
return true;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents))
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
return AddImageSkiaRep(image, data, size, scale_factor);
}
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
const base::FilePath& path) {
bool succeed = false;
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (MatchPattern(filename, "*@*x"))
// Don't search for other representations if the DPI has been specified.
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
else
succeed |= AddImageSkiaRep(image, path, 1.0f);
for (const ScaleFactorPair& pair : kScaleFactorPairs)
succeed |= AddImageSkiaRep(image,
path.InsertBeforeExtensionASCII(pair.name),
pair.scale);
return succeed;
}
#if defined(OS_MACOSX)
bool IsTemplateImage(const base::FilePath& path) {
return (MatchPattern(path.value(), "*Template.*") ||
MatchPattern(path.value(), "*Template@*x.*"));
}
#endif
v8::Persistent<v8::ObjectTemplate> template_;
} // namespace
NativeImage::NativeImage() {}
NativeImage::NativeImage(const gfx::Image& image) : image_(image) {}
NativeImage::~NativeImage() {}
mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("toPng", &NativeImage::ToPNG)
.SetMethod("toJpeg", &NativeImage::ToJPEG)
.SetMethod("toDataUrl", &NativeImage::ToDataURL)
.SetMethod("isEmpty", &NativeImage::IsEmpty)
.SetMethod("getSize", &NativeImage::GetSize)
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
v8::Handle<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
return node::Buffer::New(isolate,
reinterpret_cast<const char*>(png->front()),
png->size());
}
v8::Handle<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
std::vector<unsigned char> output;
gfx::JPEG1xEncodedDataFromImage(image_, quality, &output);
return node::Buffer::New(isolate,
reinterpret_cast<const char*>(&output.front()),
output.size());
}
std::string NativeImage::ToDataURL() {
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
std::string data_url;
data_url.insert(data_url.end(), png->front(), png->front() + png->size());
base::Base64Encode(data_url, &data_url);
data_url.insert(0, "data:image/png;base64,");
return data_url;
}
bool NativeImage::IsEmpty() {
return image_.IsEmpty();
}
gfx::Size NativeImage::GetSize() {
return image_.Size();
}
// static
mate::Handle<NativeImage> NativeImage::CreateEmpty(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new NativeImage);
}
// static
mate::Handle<NativeImage> NativeImage::Create(
v8::Isolate* isolate, const gfx::Image& image) {
return mate::CreateHandle(isolate, new NativeImage(image));
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromPNG(
v8::Isolate* isolate, const char* buffer, size_t length) {
gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
reinterpret_cast<const unsigned char*>(buffer), length);
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromJPEG(
v8::Isolate* isolate, const char* buffer, size_t length) {
gfx::Image image = gfx::ImageFrom1xJPEGEncodedData(
reinterpret_cast<const unsigned char*>(buffer), length);
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromPath(
v8::Isolate* isolate, const base::FilePath& path) {
gfx::ImageSkia image_skia;
PopulateImageSkiaRepsFromPath(&image_skia, path);
gfx::Image image(image_skia);
#if defined(OS_MACOSX)
if (IsTemplateImage(path))
MakeTemplateImage(&image);
#endif
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
mate::Arguments* args, v8::Handle<v8::Value> buffer) {
double scale_factor = 1.;
args->GetNext(&scale_factor);
gfx::ImageSkia image_skia;
AddImageSkiaRep(&image_skia,
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer),
scale_factor);
return Create(args->isolate(), gfx::Image(image_skia));
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromDataURL(
v8::Isolate* isolate, const GURL& url) {
std::string mime_type, charset, data;
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
if (mime_type == "image/png")
return CreateFromPNG(isolate, data.c_str(), data.size());
else if (mime_type == "image/jpeg")
return CreateFromJPEG(isolate, data.c_str(), data.size());
}
return CreateEmpty(isolate);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("createEmpty", &atom::api::NativeImage::CreateEmpty);
dict.SetMethod("createFromPath", &atom::api::NativeImage::CreateFromPath);
dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer);
dict.SetMethod("createFromDataUrl",
&atom::api::NativeImage::CreateFromDataURL);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_native_image, Initialize)

View file

@ -0,0 +1,82 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#include <string>
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
#include "ui/gfx/image/image.h"
class GURL;
namespace base {
class FilePath;
}
namespace gfx {
class Size;
}
namespace mate {
class Arguments;
}
namespace atom {
namespace api {
class NativeImage : public mate::Wrappable {
public:
static mate::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate);
static mate::Handle<NativeImage> Create(
v8::Isolate* isolate, const gfx::Image& image);
static mate::Handle<NativeImage> CreateFromPNG(
v8::Isolate* isolate, const char* buffer, size_t length);
static mate::Handle<NativeImage> CreateFromJPEG(
v8::Isolate* isolate, const char* buffer, size_t length);
static mate::Handle<NativeImage> CreateFromPath(
v8::Isolate* isolate, const base::FilePath& path);
static mate::Handle<NativeImage> CreateFromBuffer(
mate::Arguments* args, v8::Handle<v8::Value> buffer);
static mate::Handle<NativeImage> CreateFromDataURL(
v8::Isolate* isolate, const GURL& url);
// The default constructor should only be used by image_converter.cc.
NativeImage();
const gfx::Image& image() const { return image_; }
protected:
explicit NativeImage(const gfx::Image& image);
virtual ~NativeImage();
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
#if defined(OS_MACOSX)
// Mark the image as template image if possible.
static void MakeTemplateImage(gfx::Image* image);
#endif
v8::Handle<v8::Value> ToPNG(v8::Isolate* isolate);
v8::Handle<v8::Value> ToJPEG(v8::Isolate* isolate, int quality);
std::string ToDataURL();
bool IsEmpty();
gfx::Size GetSize();
gfx::Image image_;
DISALLOW_COPY_AND_ASSIGN(NativeImage);
};
} // namespace api
} // namespace atom
#endif // ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_

View file

@ -0,0 +1,20 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/api/atom_api_native_image.h"
#import <Cocoa/Cocoa.h>
namespace atom {
namespace api {
// static
void NativeImage::MakeTemplateImage(gfx::Image* image) {
[image->AsNSImage() setTemplate:YES];
}
} // namespace api
} // namespace atom

View file

@ -9,4 +9,5 @@ else
read: (format, type='standard') -> binding._read format, type
readText: (type='standard') -> binding._readText type
writeText: (text, type='standard') -> binding._writeText text, type
readImage: (type='standard') -> binding._readImage type
clear: (type='standard') -> binding._clear type

View file

@ -0,0 +1 @@
module.exports = process.atomBinding 'native_image'

View file

@ -4,124 +4,48 @@
#include "atom/common/native_mate_converters/image_converter.h"
#include <string>
#include <vector>
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/base/layout.h"
#if !defined(OS_MACOSX)
namespace mate {
namespace {
struct ScaleFactorPair {
const char* name;
float scale;
};
ScaleFactorPair kScaleFactorPairs[] = {
// The "@2x" is put as first one to make scale matching faster.
{ "@2x" , 2.0f },
{ "@3x" , 3.0f },
{ "@1x" , 1.0f },
{ "@4x" , 4.0f },
{ "@5x" , 5.0f },
{ "@1.25x" , 1.25f },
{ "@1.33x" , 1.33f },
{ "@1.4x" , 1.4f },
{ "@1.5x" , 1.5f },
{ "@1.8x" , 1.8f },
{ "@2.5x" , 2.5f },
};
float GetScaleFactorFromPath(const base::FilePath& path) {
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
// We don't try to convert string to float here because it is very very
// expensive.
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
return kScaleFactorPairs[i].scale;
}
return 1.0f;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents))
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (!decoded)
return false;
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
return true;
}
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
const base::FilePath& path) {
bool succeed = false;
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (MatchPattern(filename, "*@*x"))
// Don't search for other representations if the DPI has been specified.
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
else
succeed |= AddImageSkiaRep(image, path, 1.0f);
for (const ScaleFactorPair& pair : kScaleFactorPairs)
succeed |= AddImageSkiaRep(image,
path.InsertBeforeExtensionASCII(pair.name),
pair.scale);
return succeed;
}
} // namespace
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::ImageSkia* out) {
if (val->IsNull())
return true;
base::FilePath path;
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
gfx::Image image;
if (!ConvertFromV8(isolate, val, &image))
return false;
return PopulateImageSkiaRepsFromPath(out, path);
*out = image.AsImageSkia();
return true;
}
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out) {
gfx::ImageSkia image;
if (!ConvertFromV8(isolate, val, &image))
if (val->IsNull())
return true;
Handle<atom::api::NativeImage> native_image;
if (!ConvertFromV8(isolate, val, &native_image)) {
// Try converting from file path.
base::FilePath path;
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
return false;
*out = gfx::Image(image);
native_image = atom::api::NativeImage::CreateFromPath(isolate, path);
if (native_image->image().IsEmpty())
return false;
}
*out = native_image->image();
return true;
}
} // namespace mate
v8::Handle<v8::Value> Converter<gfx::Image>::ToV8(v8::Isolate* isolate,
const gfx::Image& val) {
return ConvertToV8(isolate, atom::api::NativeImage::Create(isolate, val));
}
#endif // !defined(OS_MACOSX)
} // namespace mate

View file

@ -26,6 +26,8 @@ struct Converter<gfx::Image> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out);
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
const gfx::Image& val);
};
} // namespace mate

View file

@ -1,60 +0,0 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/native_mate_converters/image_converter.h"
#import <Cocoa/Cocoa.h>
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace {
bool IsTemplateImage(const std::string& path) {
return (MatchPattern(path, "*Template.*") ||
MatchPattern(path, "*Template@*x.*"));
}
} // namespace
namespace mate {
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::ImageSkia* out) {
gfx::Image image;
if (!ConvertFromV8(isolate, val, &image))
return false;
*out = image.AsImageSkia();
return true;
}
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out) {
if (val->IsNull())
return true;
std::string path;
if (!ConvertFromV8(isolate, val, &path))
return false;
base::scoped_nsobject<NSImage> image([[NSImage alloc]
initByReferencingFile:base::SysUTF8ToNSString(path)]);
if (![image isValid])
return false;
if (IsTemplateImage(path))
[image setTemplate:YES];
*out = gfx::Image(image.release());
return true;
}
} // namespace mate

View file

@ -72,6 +72,7 @@ REFERENCE_MODULE(atom_common_asar);
REFERENCE_MODULE(atom_common_clipboard);
REFERENCE_MODULE(atom_common_crash_reporter);
REFERENCE_MODULE(atom_common_id_weak_map);
REFERENCE_MODULE(atom_common_native_image);
REFERENCE_MODULE(atom_common_screen);
REFERENCE_MODULE(atom_common_shell);
REFERENCE_MODULE(atom_common_v8_util);

View file

@ -46,6 +46,7 @@ Modules for both sides:
* [clipboard](api/clipboard.md)
* [crash-reporter](api/crash-reporter.md)
* [native-image](api/native-image.md)
* [screen](api/screen.md)
* [shell](api/shell.md)

View file

@ -43,13 +43,13 @@ You can also create a window without chrome by using
other windows
* `fullscreen` Boolean - Whether the window should show in fullscreen, when
set to `false` the fullscreen button would also be hidden on OS X
* `skip-taskbar` Boolean - Do not show window in taskbar
* `skip-taskbar` Boolean - Do not show window in Taskbar
* `zoom-factor` Number - The default zoom factor of the page, zoom factor is
zoom percent / 100, so `3.0` represents `300%`
* `kiosk` Boolean - The kiosk mode
* `title` String - Default window title
* `icon` [Image](image.md) - The window icon, when omitted on Windows the
executable's icon would be used as window icon
* `icon` [NativeImage](native-image.md) - The window icon, when omitted on
Windows the executable's icon would be used as window icon
* `show` Boolean - Whether window should be shown when created
* `frame` Boolean - Specify `false` to create a
[Frameless Window](frameless-window.md)
@ -415,7 +415,7 @@ Starts or stops flashing the window to attract user's attention.
* `skip` Boolean
Makes the window do not show in taskbar.
Makes the window do not show in Taskbar.
### BrowserWindow.setKiosk(flag)
@ -545,8 +545,11 @@ it will assume `app.getName().desktop`.
### BrowserWindow.setOverlayIcon(overlay, description)
* `overlay` [Image](image.md) - the icon to display on the bottom right corner of the Taskbar icon. If this parameter is `null`, the overlay is cleared.
* `description` String - a description that will be provided to Accessibility screenreaders
* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom
right corner of the Taskbar icon. If this parameter is `null`, the overlay is
cleared
* `description` String - a description that will be provided to Accessibility
screen readers
Sets a 16px overlay onto the current Taskbar icon, usually used to convey some sort of application status or to passively notify the user.

View file

@ -76,7 +76,7 @@ would be passed via `callback(filename)`
* `title` String - Title of the message box, some platforms will not show it
* `message` String - Content of the message box
* `detail` String - Extra information of the message
* `icon` [Image](image.md)
* `icon` [NativeImage](native-image.md)
* `callback` Function
Shows a message box, it will block until the message box is closed. It returns

View file

@ -1,7 +1,7 @@
# Image
# NativeImage
In atom-shell images are represented by their file paths, we currently do not
support in-memory images or remote images.
In atom-shell for the APIs that take images, you can pass either file paths or
`NativeImage` instances. When passing `null`, an empty image will be used.
For example when creating tray or setting window's icon, you can pass image's
file path as `String` to represent an image:
@ -11,12 +11,18 @@ var appIcon = new Tray('/Users/somebody/images/icon.png');
var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'});
```
Or read the image from clipboard:
```javascript
var clipboard = require('clipboard');
var image = clipboard.readImage();
var appIcon = new Tray(image);
```
## Supported formats
On Mac all formats supported by the system can be used, while on Linux and
Windows only `PNG` and `JPG` formats are supported.
So it is recommended to use `PNG` images for all cases.
Currently `PNG` and `JPEG` are supported, and it is recommended to use `PNG`
because it supports alpha channel and image is usually not compressed.
## High resolution image
@ -73,3 +79,55 @@ To mark an image as template image, its filename should end with the word
* `xxxTemplate.png`
* `xxxTemplate@2x.png`
## nativeImage.createEmpty()
Creates an empty `NativeImage` instance.
## nativeImage.createFromPath(path)
* `path` String
Creates a new `NativeImage` instance from file located at `path`.
## nativeImage.createFromBuffer(buffer[, scaleFactor])
* `buffer` [Buffer][buffer]
* `scaleFactor` Double
Creates a new `NativeImage` instance from `buffer`. The `scaleFactor` is 1.0 by
default.
## nativeImage.createFromDataUrl(dataUrl)
* `dataUrl` String
Creates a new `NativeImage` instance from `dataUrl`.
## Class: NativeImage
This class is used to represent an image.
### NativeImage.toPng()
Returns a [Buffer][buffer] that contains image's `PNG` encoded data.
### NativeImage.toJpeg(quality)
* `quality` Integer
Returns a [Buffer][buffer] that contains image's `JPEG` encoded data.
### NativeImage.toDataUrl()
Returns the data URL of image.
### NativeImage.isEmpty()
Returns whether the image is empty.
### NativeImage.getSize()
Returns the size of the image.
[buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer

View file

@ -40,7 +40,7 @@ rely on `clicked` event and always attach a context menu to the tray icon.
### new Tray(image)
* `image` [Image](image.md)
* `image` [NativeImage](native-image.md)
Creates a new tray icon associated with the `image`.
@ -79,13 +79,13 @@ Destroys the tray icon immediately.
### Tray.setImage(image)
* `image` [Image](image.md)
* `image` [NativeImage](native-image.md)
Sets the `image` associated with this tray icon.
### Tray.setPressedImage(image)
* `image` [Image](image.md)
* `image` [NativeImage](native-image.md)
Sets the `image` associated with this tray icon when pressed.
@ -114,7 +114,7 @@ This is only implmented on OS X.
### Tray.displayBalloon(options)
* `options` Object
* `icon` [Image](image.md)
* `icon` [NativeImage](native-image.md)
* `title` String
* `content` String

View file

@ -78,7 +78,7 @@ describe 'browser-window module', ->
describe 'BrowserWindow.capturePage(rect, callback)', ->
it 'calls the callback with a Buffer', (done) ->
w.capturePage {x: 0, y: 0, width: 100, height: 100}, (image) ->
assert.equal image.constructor.name, 'Buffer'
assert.equal image.isEmpty(), true
done()
describe 'BrowserWindow.setSize(width, height)', ->

2
vendor/native_mate vendored

@ -1 +1 @@
Subproject commit 1116a36c15ac3e65720cf12d38a3308f40f7ea58
Subproject commit 8d537ee2b6da29c1aa38928590d4c56700e1c69b