summaryrefslogtreecommitdiff
path: root/rotord/src/cvimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/cvimage.cpp')
-rw-r--r--rotord/src/cvimage.cpp156
1 files changed, 156 insertions, 0 deletions
diff --git a/rotord/src/cvimage.cpp b/rotord/src/cvimage.cpp
new file mode 100644
index 0000000..c18c585
--- /dev/null
+++ b/rotord/src/cvimage.cpp
@@ -0,0 +1,156 @@
+#include "cvimage.h"
+
+using namespace std;
+
+namespace Rotor {
+ Image & Image::operator+=(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ rgb+=other.rgb;
+ }
+ return *this;
+ }
+ Image & Image::operator*=(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot multiply images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ //rgb/=other.rgb; //does funny glitchy stuff
+ //could use cv::Mat.mul() here
+ for (int i=0;i<w*h*3;i++){
+ //calculate with tables
+ rgb.data[i]=pixels.multiply[rgb.data[i]][other.rgb.data[i]];
+ }
+ }
+ return *this;
+ }
+ Image & Image::operator^=(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ rgb^=other.rgb;
+ }
+ return *this;
+ }
+ Image & Image::add_wrap(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ for (int i=0;i<w*h*3;i++){
+ //creates rainbow overload, openCV doesn't do this
+ rgb.data[i]=(unsigned char)(((int)other.rgb.data[i]+(int)rgb.data[i]));
+ }
+ }
+ return *this;
+ }
+ Image & Image::divide_wrap(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ for (int i=0;i<w*h*3;i++){
+ //creates rainbow overload, openCV doesn't do this
+ rgb/=other.rgb; //does funny glitchy stuff
+ }
+ }
+ return *this;
+ }
+ //THIS OPENCV VERSION IS SLOWER THAN THE OLDSKOOL VERSION BELOW
+ Image & Image::alpha_blend_cv(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot blend images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ //why not??
+ }
+ else if (!other.alpha.data){
+ //default to full on alpha
+ rgb=other.rgb.clone();
+ }
+ else {
+ //overlay the other image based on its alpha values
+ //https://gist.github.com/Brick85/5009046 - this is a dumb way to do it?
+ //how to invert a matrix?
+ //'invert' is matrix invert - different
+ //subtract from a scalar (1) ?
+ vector<cv::Mat> ichans,ochans;
+ vector<cv::Mat> compchans;
+ cv::split(rgb,ichans);
+ cv::split(other.rgb,ochans);
+ uint8_t b=0xFF;
+ cv::Mat iA=b-other.alpha;
+ for (int i=0;i<3;i++) {
+ compchans.push_back(ichans[i].mul(iA,1.0/255.0)+ochans[i].mul(other.alpha,1.0/255.0));
+ }
+ merge(compchans,rgb);
+ //rgb+=other.rgb;
+ //for (int i=0;i<w*h*3;i++) {
+ // rgb.data[i]=(uint8_t)(((((int)rgb.data[i])*(0xFF-other.alpha.data[i/3]))>>8)+((((int)other.rgb.data[i])*((int)other.alpha.data[i/3]))>>8));
+ //}
+ }
+
+ return *this;
+ }
+ Image & Image::alpha_blend(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot blend images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ //why not??
+ }
+ else if (!other.alpha.data){
+ //default to full on alpha
+ rgb=other.rgb.clone();
+ }
+ else {
+ for (int i=0;i<w*h*3;i++) {
+ rgb.data[i]=(uint8_t)(((((int)rgb.data[i])*(0xFF-other.alpha.data[i/3]))>>8)+((((int)other.rgb.data[i])*((int)other.alpha.data[i/3]))>>8));
+ }
+ }
+ return *this;
+ }
+ Image & Image::alpha_merge(const Image &other) {
+ //converts the incoming image to monochrome and inserts it into the alpha channel of this image
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot merge alpha with different size! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ cv::cvtColor(other.rgb,alpha,CV_RGB2GRAY);
+ }
+ return *this;
+ }
+ //channel rearrangement
+ //RGBAZ - these are channels 0-4
+ //HSB - can also have these virtual channels 5-7
+ //convert channels- int outChannel[5] - {0,1,2,-5,4} - this mapping sends inverted brightness to alpha
+
+ //scalar operations allocate a new image.
+ //maybe this could not be the case if the data is owned by this image?
+ //need to look into auto_ptr
+ Image & Image::operator*=(const float &amount) {
+ rgb*=amount;
+ return *this;
+ }
+ Image * Image::operator*(const float &amount) {
+ Image *other=new Image(w,h);
+ other->rgb=rgb*amount;
+ return other;
+ }
+ Image * Image::operator+(const float &amount) {
+ uint8_t amt=(uint8_t)(amount*255.0f);
+ Image *other=new Image(w,h);
+ other->rgb=rgb+amt;
+ return other;
+ }
+ Image * Image::operator-(const float &amount) {
+ uint8_t amt=(uint8_t)(amount*255.0f);
+ Image *other=new Image(w,h);
+ other->rgb=rgb-amt;
+ return other;
+ }
+ Image * Image::operator/(const float &amount) {
+ Image *other=new Image(w,h);
+ other->rgb=rgb/amount;
+ return other;
+ }
+}