refactor: 重构tobuffer相关业务逻辑

This commit is contained in:
zhiwei 2020-05-29 10:12:28 +08:00
parent a0b850df2e
commit bc0a8396ea
4 changed files with 129 additions and 89 deletions

View File

@ -121,42 +121,47 @@ namespace NodeBinding
Napi::Value Canvas::createJPGStreamSync(const Napi::CallbackInfo &info)
{
NodeBinding::checkArgs(info, 2);
Napi::Function callback = info[0].As<Napi::Function>();
if (this->mRenderContext)
{
this->mRenderContext->makeCurrent();
this->mRenderContext->drawFrame();
}
unsigned char *data = (unsigned char *)malloc(1 * sizeof(unsigned char));
unsigned long size = 0;
int ret = this->mRenderContext->getImagePixelJPG(&data, size);
if (ret == 0 && size > 0)
{
//handlescope 表示作用域,一般调用callback函数时使用
Napi::HandleScope scope(info.Env());
Napi::Buffer<unsigned char> buffer = Napi::Buffer<unsigned char>::Copy(info.Env(), data, size);
callback.Call({info.Env().Null(),
buffer,
Napi::Number::New(info.Env(), size)});
}
else
{
Napi::HandleScope scope(info.Env());
callback.Call({Napi::String::New(Env(), "createJPGStreamFail"),
info.Env().Null(),
info.Env().Null()});
}
if (data)
{
delete data;
data = nullptr;
}
Napi::Buffer<unsigned char> buffer = this->getJPGBuffer(info, size);
Napi::Function callback = info[0].As<Napi::Function>();
//handlescope 表示作用域,一般调用callback函数时使用
Napi::HandleScope scope(info.Env());
callback.Call({info.Env().Null(),
buffer,
Napi::Number::New(info.Env(), size)});
// }
// else
// {
// Napi::HandleScope scope(info.Env());
// callback.Call({Napi::String::New(Env(), "createJPGStreamFail"),
// info.Env().Null(),
// info.Env().Null()});
// }
}
Napi::Value Canvas::createPNGStreamSync(const Napi::CallbackInfo &info)
{
NodeBinding::checkArgs(info, 2);
unsigned long size = 0;
Napi::Buffer<unsigned char> buffer = this->getPNGBuffer(info, size);
Napi::Function callback = info[0].As<Napi::Function>();
//handlescope 表示作用域,一般调用callback函数时使用
Napi::HandleScope scope(info.Env());
callback.Call({info.Env().Null(),
buffer,
Napi::Number::New(info.Env(), size)});
// }
// else
// {
// Napi::HandleScope scope(info.Env());
// callback.Call({Napi::String::New(Env(), "createPNGStreamFail"),
// info.Env().Null(),
// info.Env().Null()});
// }
}
Napi::Buffer<unsigned char> Canvas::getPNGBuffer(const Napi::CallbackInfo &info, unsigned long &size)
{
if (this->mRenderContext)
{
this->mRenderContext->makeCurrent();
@ -166,37 +171,65 @@ namespace NodeBinding
int ret = this->mRenderContext->getImagePixelPNG(in);
if (ret == 0)
{
//handlescope 表示作用域,一般调用callback函数时使用
Napi::HandleScope scope(info.Env());
Napi::Buffer<unsigned char> buffer = Napi::Buffer<unsigned char>::Copy(info.Env(), &in[0], in.size());
callback.Call({info.Env().Null(),
buffer,
Napi::Number::New(info.Env(), in.size())});
}
else
{
Napi::HandleScope scope(info.Env());
callback.Call({Napi::String::New(Env(), "createPNGStreamFail"),
info.Env().Null(),
info.Env().Null()});
}
}
Napi::Value Canvas::Buffer(const Napi::CallbackInfo &info)
{
if (info.Length() == 0)
{
if (this->mRenderContext)
{
this->mRenderContext->makeCurrent();
this->mRenderContext->drawFrame();
}
std::vector<unsigned char> in;
int ret = this->mRenderContext->getImagePixelPNG(in);
size = in.size();
return Napi::Buffer<unsigned char>::Copy(info.Env(), &in[0], in.size());
}
else
{
return info.Env().Undefined();
throwError(info.Env(), "createPNGBuffer fail");
}
}
Napi::Buffer<unsigned char> Canvas::getJPGBuffer(const Napi::CallbackInfo &info, unsigned long &size)
{
if (this->mRenderContext)
{
this->mRenderContext->makeCurrent();
this->mRenderContext->drawFrame();
}
unsigned char *data = nullptr;
int ret = this->mRenderContext->getImagePixelJPG(&data, size);
if (ret == 0)
{
return Napi::Buffer<unsigned char>::Copy(info.Env(), data, size);
}
else
{
throwError(info.Env(), "createJPGBuffer fail");
}
}
Napi::Buffer<unsigned char> Canvas::getRawDataBuffer(const Napi::CallbackInfo &info, unsigned long &size)
{
unsigned char *data = new unsigned char[4 * mWidth * mHeight];
int ret = this->mRenderContext->readPixelAndSampleFromCurrentCtx(data);
return Napi::Buffer<unsigned char>::Copy(info.Env(), data, 4 * mWidth * mHeight);
}
Napi::Value Canvas::Buffer(const Napi::CallbackInfo &info)
{
unsigned long size = 0;
//默认输出png 编码
if (info.Length() == 0)
{
return this->getPNGBuffer(info, size);
}
else
{
if (info.Length() == 1)
{
std::string mimeType = info[0].As<Napi::String>().Utf8Value();
if (mimeType == "image/png")
{
return this->getPNGBuffer(info, size);
}
else if (mimeType == "image/jpeg")
{
return this->getJPGBuffer(info, size);
}
else if (mimeType == "raw")
{
return this->getRawDataBuffer(info, size);
}
}
return info.Env().Null();
}
}
Canvas::~Canvas()

View File

@ -9,35 +9,38 @@
#include <memory>
namespace NodeBinding
{
class Canvas : public Napi::ObjectWrap<Canvas>
{
public:
static void Init(Napi::Env env,Napi::Object exports);
Canvas(const Napi::CallbackInfo &info);
virtual ~Canvas();
static Napi::Object NewInstance(Napi::Env env, Napi::Value arg, Napi::Value arg2);
Napi::ObjectReference mRef;
int getWidth();
int getHeight();
std::shared_ptr<GRenderContext> mRenderContext;
private:
static Napi::FunctionReference constructor;
Napi::Value getWidth(const Napi::CallbackInfo &info);
Napi::Value getHeight(const Napi::CallbackInfo &info);
Napi::Value getContext(const Napi::CallbackInfo &info);
Napi::Value createPNGStreamSync(const Napi::CallbackInfo &info);
Napi::Value createJPGStreamSync(const Napi::CallbackInfo &info);
Napi::Value Buffer(const Napi::CallbackInfo &info);
Napi::ObjectReference context2dRef;
class Canvas : public Napi::ObjectWrap<Canvas>
{
public:
static void Init(Napi::Env env, Napi::Object exports);
Canvas(const Napi::CallbackInfo &info);
virtual ~Canvas();
static Napi::Object NewInstance(Napi::Env env, Napi::Value arg, Napi::Value arg2);
Napi::ObjectReference mRef;
int getWidth();
int getHeight();
std::shared_ptr<GRenderContext> mRenderContext;
void setWidth(const Napi::CallbackInfo &info, const Napi::Value &value);
void setHeight(const Napi::CallbackInfo &info, const Napi::Value &value);
void createPNG(const Napi::CallbackInfo &info);
void createJPEG(const Napi::CallbackInfo &info);
private:
static Napi::FunctionReference constructor;
Napi::Value getWidth(const Napi::CallbackInfo &info);
Napi::Value getHeight(const Napi::CallbackInfo &info);
Napi::Value getContext(const Napi::CallbackInfo &info);
Napi::Value createPNGStreamSync(const Napi::CallbackInfo &info);
Napi::Value createJPGStreamSync(const Napi::CallbackInfo &info);
Napi::Value Buffer(const Napi::CallbackInfo &info);
Napi::Buffer<unsigned char> getPNGBuffer(const Napi::CallbackInfo &info, unsigned long &size);
Napi::Buffer<unsigned char> getJPGBuffer(const Napi::CallbackInfo &info, unsigned long &size);
Napi::Buffer<unsigned char> getRawDataBuffer(const Napi::CallbackInfo &info, unsigned long &size);
Napi::ObjectReference context2dRef;
int mWidth = 0;
int mHeight = 0;
};
void setWidth(const Napi::CallbackInfo &info, const Napi::Value &value);
void setHeight(const Napi::CallbackInfo &info, const Napi::Value &value);
void createPNG(const Napi::CallbackInfo &info);
void createJPEG(const Napi::CallbackInfo &info);
int mWidth = 0;
int mHeight = 0;
};
} // namespace NodeBinding
#endif

View File

@ -3,7 +3,6 @@ const canvas = createCanvas(400, 400);
const ctx = canvas.getContext('2d')
const fs = require('fs')
const path = require('path');
const out = fs.createWriteStream(path.join(__dirname, "..") + '/demo1.png');
ctx.fillRect(0, 0, 150, 150) // Draw a rectangle with default settings
ctx.save() // Save the default state
@ -22,7 +21,13 @@ ctx.fillRect(45, 45, 60, 60) // Draw a rectangle with restored settings
ctx.restore() // Restore original state
ctx.fillRect(60, 60, 30, 30) // Draw a rectangle with restored settings
fs.writeFile(`${__dirname}/output.png`, canvas.toBuffer(), err => {
fs.writeFile(`${path.join(__dirname, "..")}/tobuffer.png`, canvas.toBuffer("image/png"), err => {
if (err) {
throw err;
}
});
fs.writeFile(`${path.join(__dirname, "..")}/tobuffer.jpg`, canvas.toBuffer("image/jpeg"), err => {
if (err) {
throw err;
}

View File

@ -41,6 +41,7 @@ public:
void makeCurrent();
int getImagePixelPNG(std::vector<unsigned char> &in);
int getImagePixelJPG(unsigned char **data,unsigned long &size);
int readPixelAndSampleFromCurrentCtx(unsigned char *data);
private:
std::shared_ptr<gcanvas::GCanvas> mCanvas;
void initCanvas();
@ -56,9 +57,7 @@ private:
GLuint mFboId = 0;
GLuint mRenderBuffer = 0;
GLuint mDepthRenderbuffer = 0;
std::vector<int> textures;
int readPixelAndSampleFromCurrentCtx(unsigned char *data);
std::vector<int> textures;
};
} // namespace NodeBinding