Skip to content

Commit

Permalink
Add text operator
Browse files Browse the repository at this point in the history
  • Loading branch information
darbyjohnston committed Aug 10, 2024
1 parent 974fb9a commit 4a06eaf
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 1 deletion.
106 changes: 106 additions & 0 deletions data/Text.otio
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"OTIO_SCHEMA": "Timeline.1",
"metadata": {},
"name": "SimpleOver",
"tracks": {
"OTIO_SCHEMA": "Stack.1",
"children": [
{
"OTIO_SCHEMA": "Track.1",
"children": [
{
"OTIO_SCHEMA": "Clip.1",
"media_reference": {
"OTIO_SCHEMA": "ExternalReference.1",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24,
"value": 24
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24,
"value": 0
}
},
"target_url": "Color_Black.png"
},
"effects": [
{
"OTIO_SCHEMA": "TextImageEffect.1",
"effect_name": "",
"x": 100,
"y": 200,
"text": "toucan",
"font_size": 200,
"font_name": "",
"red": 0.8,
"green": 0.0,
"blue": 0.3,
"alpha": 1.0
},
{
"OTIO_SCHEMA": "TextImageEffect.1",
"effect_name": "",
"x": 200,
"y": 350,
"text": "toucan",
"font_size": 200,
"font_name": "",
"red": 0.3,
"green": 0.8,
"blue": 0.1,
"alpha": 1.0
},
{
"OTIO_SCHEMA": "TextImageEffect.1",
"effect_name": "",
"x": 300,
"y": 500,
"text": "toucan",
"font_size": 200,
"font_name": "",
"red": 0.9,
"green": 0.7,
"blue": 0.1,
"alpha": 1.0
},
{
"OTIO_SCHEMA": "TextImageEffect.1",
"effect_name": "",
"x": 400,
"y": 650,
"text": "toucan",
"font_size": 200,
"font_name": "",
"red": 0.9,
"green": 0.5,
"blue": 0.1,
"alpha": 1.0
}
],
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24,
"value": 24
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24,
"value": 0
}
},
"name": "Text"
}
],
"kind": "Video",
"name": "Video"
}
],
"name": "Stack"
}
}
2 changes: 2 additions & 0 deletions lib/toucan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(HEADERS
Init.h
NoiseImageOp.h
ReadImageOp.h
TextImageOp.h
TimelineTraverse.h)
set(SOURCE
CheckersImageOp.cpp
Expand All @@ -15,6 +16,7 @@ set(SOURCE
Init.cpp
NoiseImageOp.cpp
ReadImageOp.cpp
TextImageOp.cpp
TimelineTraverse.cpp)

add_library(toucan ${HEADERS} ${SOURCE})
Expand Down
2 changes: 2 additions & 0 deletions lib/toucan/Init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "CheckersImageOp.h"
#include "FillImageOp.h"
#include "NoiseImageOp.h"
#include "TextImageOp.h"

#include <opentimelineio/typeRegistry.h>

Expand All @@ -17,5 +18,6 @@ namespace toucan
OTIO_NS::TypeRegistry::instance().register_type<CheckersImageEffect>();
OTIO_NS::TypeRegistry::instance().register_type<FillImageEffect>();
OTIO_NS::TypeRegistry::instance().register_type<NoiseImageEffect>();
OTIO_NS::TypeRegistry::instance().register_type<TextImageEffect>();
}
}
111 changes: 111 additions & 0 deletions lib/toucan/TextImageOp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Darby Johnston
// All rights reserved.

#include "TextImageOp.h"

#include <OpenImageIO/imagebufalgo.h>

namespace toucan
{
TextImageOp::TextImageOp(const TextData& data) :
_data(data)
{}

TextImageOp::~TextImageOp()
{}

const TextData& TextImageOp::getData() const
{
return _data;
}

void TextImageOp::setData(const TextData& value)
{
_data = value;
}

OIIO::ImageBuf TextImageOp::exec()
{
OIIO::ImageBuf buf;
if (!_inputs.empty())
{
buf = _inputs[0]->exec();
OIIO::ImageBufAlgo::render_text(
buf,
_data.pos.x,
_data.pos.y,
_data.text,
_data.fontSize,
_data.fontName,
{ _data.color.x, _data.color.y, _data.color.z, _data.color.w });
}
return buf;
}

TextImageEffect::TextImageEffect(
std::string const& name,
std::string const& effect_name,
OTIO_NS::AnyDictionary const& metadata) :
IEffect(name, effect_name, metadata)
{}

TextImageEffect::~TextImageEffect()
{}

const TextData& TextImageEffect::getData() const
{
return _data;
}

void TextImageEffect::setData(const TextData & value)
{
_data = value;
}

std::shared_ptr<IImageOp> TextImageEffect::createOp()
{
return std::make_shared<TextImageOp>(_data);
}

bool TextImageEffect::read_from(Reader& reader)
{
int64_t x = 0;
int64_t y = 0;
int64_t fontSize = 0;
IMATH_NAMESPACE::V4d color;
bool out =
reader.read("x", &x) &&
reader.read("y", &y) &&
reader.read("text", &_data.text) &&
reader.read("font_size", &fontSize) &&
reader.read("font_name", &_data.fontName) &&
reader.read("red", &color.x) &&
reader.read("green", &color.y) &&
reader.read("blue", &color.z) &&
reader.read("alpha", &color.w) &&
IEffect::read_from(reader);
if (out)
{
_data.pos.x = x;
_data.pos.y = y;
_data.fontSize = fontSize;
_data.color = color;
}
return out;
}

void TextImageEffect::write_to(Writer& writer) const
{
IEffect::write_to(writer);
writer.write("x", static_cast<int64_t>(_data.pos.x));
writer.write("y", static_cast<int64_t>(_data.pos.y));
writer.write("text", _data.text);
writer.write("font_size", static_cast<int64_t>(_data.fontSize));
writer.write("font_name", _data.fontName);
writer.write("red", static_cast<double>(_data.color.x));
writer.write("green", static_cast<double>(_data.color.y));
writer.write("blue", static_cast<double>(_data.color.z));
writer.write("alpha", static_cast<double>(_data.color.w));
}
}
69 changes: 69 additions & 0 deletions lib/toucan/TextImageOp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Darby Johnston
// All rights reserved.

#pragma once

#include <toucan/ImageOp.h>

#include <filesystem>

namespace toucan
{
//! Text data.
struct TextData
{
IMATH_NAMESPACE::V2i pos = IMATH_NAMESPACE::V2i(0, 0);
std::string text;
int fontSize = 16;
std::string fontName;
IMATH_NAMESPACE::V4f color = IMATH_NAMESPACE::V4f(1.F, 1.F, 1.F, 1.F);
};

//! Text drawing image operation.
class TextImageOp : public IImageOp
{
public:
TextImageOp(const TextData& = TextData());

virtual ~TextImageOp();

const TextData& getData() const;
void setData(const TextData&);

OIIO::ImageBuf exec() override;

private:
TextData _data;
};

//! Text drawing image OTIO effect.
class TextImageEffect : public IEffect
{
public:
struct Schema
{
static auto constexpr name = "TextImageEffect";
static int constexpr version = 1;
};

TextImageEffect(
std::string const& name = std::string(),
std::string const& effect_name = std::string(),
OTIO_NS::AnyDictionary const& metadata = OTIO_NS::AnyDictionary());

const TextData& getData() const;
void setData(const TextData&);

std::shared_ptr<IImageOp> createOp() override;

protected:
virtual ~TextImageEffect();

bool read_from(Reader&) override;
void write_to(Writer&) const override;

private:
TextData _data;
};
}
3 changes: 2 additions & 1 deletion tests/TimelineTraverseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace toucan
{
"CompOver",
"Gap",
"Patterns"
"Patterns",
"Text"
};
for (const auto& otioFile : otioFiles)
{
Expand Down

0 comments on commit 4a06eaf

Please sign in to comment.