GCanvas/node/binding/Image.cc
2020-02-11 15:57:07 +08:00

154 lines
3.9 KiB
C++

#include "Image.h"
#include "NodeBindingUtil.h"
#include <iostream>
#include <stdlib.h>
namespace NodeBinding
{
Napi::FunctionReference Image::constructor;
Image::Image(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Image>(info)
{
}
void Image::Init(Napi::Env env, Napi::Object exports)
{
Napi::HandleScope scope(env);
Napi::Function func =
DefineClass(env,
"Image",
{
InstanceAccessor("src", &Image::getSrc, &Image::setSrc),
InstanceAccessor("width", &Image::getWidth, nullptr),
InstanceAccessor("height", &Image::getHeight, nullptr),
InstanceAccessor("onload", &Image::getOnLoad, &Image::setOnLoad),
InstanceAccessor("onerror", &Image::getOnError, &Image::setOnError),
});
constructor = Napi::Persistent(func);
constructor.SuppressDestruct();
exports.Set("Image", func);
}
Napi::Value Image::getSrc(const Napi::CallbackInfo &info)
{
return Napi::String::New(info.Env(), this->src);
}
void Image::setSrc(const Napi::CallbackInfo &info, const Napi::Value &value)
{
checkArgs(info, 1);
this->src = value.As<Napi::String>().Utf8Value();
if (mWorker)
{
mWorker->url = this->src;
mWorker->Queue();
}
}
Napi::Value Image::getOnLoad(const Napi::CallbackInfo &info)
{
return this->onLoadCallback;
}
void Image::setOnLoad(const Napi::CallbackInfo &info, const Napi::Value &value)
{
checkArgs(info, 1);
this->onLoadCallback = value.As<Napi::Function>();
if (!mWorker)
{
mWorker = new ImageWorker(info.Env(), pixels, width, height);
}
mWorker->setOnLoadCallback(this->onLoadCallback);
}
void Image::setOnError(const Napi::CallbackInfo &info, const Napi::Value &value)
{
checkArgs(info, 1);
this->onErrorCallback = value.As<Napi::Function>();
if (!mWorker)
{
mWorker = new ImageWorker(info.Env(), pixels, width, height);
}
mWorker->setOnErrorCallback(onErrorCallback);
}
Napi::Value Image::getWidth(const Napi::CallbackInfo &info)
{
return Napi::Number::New(info.Env(), this->width);
}
Napi::Value Image::getHeight(const Napi::CallbackInfo &info)
{
return Napi::Number::New(info.Env(), this->height);
}
int Image::getWidth()
{
return this->width;
}
int Image::getHeight()
{
return this->height;
}
Napi::Value Image::getOnError(const Napi::CallbackInfo &info)
{
return this->onErrorCallback;
}
std::vector<unsigned char> &Image::getPixels()
{
return this->pixels;
}
void ImageWorker::setOnErrorCallback(Napi::Function func)
{
this->onErrorCallback = Napi::Persistent(func);
}
void ImageWorker::setOnLoadCallback(Napi::Function func)
{
this->onLoadCallback = Napi::Persistent(func);
}
void ImageWorker::OnOK()
{
if( this->onLoadCallback )
{
this->onLoadCallback.Call({Env().Undefined()});
}
}
void ImageWorker::OnError(const Napi::Error &e)
{
if(this->onErrorCallback)
{
this->onErrorCallback.Call({Napi::String::New(Env(), e.Message())});
}
}
void ImageWorker::Execute()
{
if (url.rfind("http", 0) == 0 || url.rfind("https", 0) == 0)
{
content.size = downloadImage(url, &content);
if ((int)content.size <= 0)
{
free(content.memory);
content.memory = nullptr;
this->SetError(std::move("Image Download Fail"));
return;
}
}
else
{ //本地文件
content.size = readLocalImage(url, &content);
if ((int)content.size <= 0)
{
free(content.memory);
content.memory = nullptr;
this->SetError(std::move("Image Read Fail"));
return;
}
}
lodepng::decode(_pixels, _width, _height, (const unsigned char *)content.memory, content.size);
free(content.memory);
content.memory = nullptr;
}
}; // namespace NodeBinding