Browse Source

draw image

master
blobt 5 years ago
parent
commit
3d19c86326
  1. 2
      CMakeLists.txt
  2. 3
      src/CMakeLists.txt
  3. 37
      src/Image.cc
  4. 77
      src/Image.h
  5. 28
      src/Raster.cc
  6. 2
      src/Raster.h
  7. 12
      src/Rgba.cc
  8. 17
      src/Rgba.h
  9. 71
      src/draw_image.cc

2
CMakeLists.txt

@ -14,10 +14,12 @@ message(STATUS "----- GTK2_LINK_LIBRARIES: ${GTK2_LINK_LIBRARIES}")
include_directories(${GTK2_INCLUDE_DIRS})
link_directories(${GTK2_LIBRARY_DIRS})
list(APPEND FC_DEP_LIBS ${GTK2_LIBRARIES})
list(APPEND FC_DEP_LIBS freeimage)
set(commom_src
Rgba.cc
Raster.cc
Image.cc
)
add_subdirectory(src)

3
src/CMakeLists.txt

@ -1,3 +1,6 @@
add_executable(draw_image draw_image.cc ${commom_src})
target_link_libraries (draw_image ${FC_DEP_LIBS})
add_executable(draw_triangle draw_triangle.cc ${commom_src})
target_link_libraries (draw_triangle ${FC_DEP_LIBS})

37
src/Image.cc

@ -0,0 +1,37 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: Image.cc
* Author: Blobt
*
* Created on February 10, 2020, 5:55 PM
*/
#include "Image.h"
#include <string.h>
Image::Image(int width, int height, void* data) {
if (width == 0 || height == 0 || data == 0) {
_width = 0;
_height = 0;
_pixel = 0;
} else {
_width = width;
_height = height;
_pixel = new unsigned int[width * height];
memcpy(_pixel, data, width * height * sizeof (unsigned int));
}
}
Image::~Image() {
delete [] _pixel;
}
Rgba Image::pixelAt(int x, int y) const {
return Rgba(_pixel[y * _width + x]);
}

77
src/Image.h

@ -0,0 +1,77 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: Image.h
* Author: Blobt
*
* Created on February 10, 2020, 5:55 PM
*/
#ifndef IMAGE_H
#define IMAGE_H
#include "Rgba.h"
#include "FreeImage.h"
#include "stdio.h"
class Image {
public:
Image(int width, int height, void* data);
virtual ~Image();
int width() const {
return _width;
}
int height() const {
return _height;
}
Rgba pixelAt(int x, int y) const;
static Image* loadFromFile(const char* fileName) {
//
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN) {
return 0;
}
//
FIBITMAP* dib = FreeImage_Load(fifmt, fileName, 0);
//
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*) FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
//
for (int i = 0; i < width * height * 4; i += 4) {
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
Image* image = new Image(width, height, (void*) pixels);
FreeImage_Unload(dib);
return image;
}
private:
int _width;
int _height;
unsigned int* _pixel;
};
#endif /* IMAGE_H */

28
src/Raster.cc

@ -13,6 +13,7 @@
#include "Rgba.h"
#include "Raster.h"
#include "Image.h"
#include <stdio.h>
#include <iostream>
#include <string.h>
@ -35,11 +36,13 @@ void Raster::drawPoint(int x, int y, Rgba color, int pointSize) {
switch (pointSize) {
case 1:
setPixel(x, y, color);
break;
case 2:
setPixel(x, y, color);
setPixel(x + 1, y, color);
setPixel(x, y + 1, color);
setPixel(x + 1, y + 1, color);
break;
case 3:
setPixel(x - 1, y - 1, color);
setPixel(x, y - 1, color);
@ -52,6 +55,7 @@ void Raster::drawPoint(int x, int y, Rgba color, int pointSize) {
setPixel(x - 1, y + 1, color);
setPixel(x, y + 1, color);
setPixel(x + 1, y + 1, color);
break;
}
}
@ -163,13 +167,13 @@ void Raster::drawSpan(const Span &span) {
Rgba color;
float length = span.xEnd - span.xStart;
int startX = tmax<int>(span.xStart, 0);
int endX = tmin<int>(span.xEnd, _width);
float scale = (startX - span.xStart) / length;
//优化3 x轴越界处理
for (int i = startX; i <= endX; i++) {
color = colorLerp(span.color1, span.color2, (float) (i - startX) / length);
@ -339,6 +343,22 @@ void Raster::drawRect(const int2* points, const Rgba* colors) {
}
}
void Raster::drawImage(int startX, int startY, const Image* image) {
/*越界部分不描画*/
int left = tmax<int>(startX, 0);
int bottom = tmax<int>(startY, 0);
int right = tmin<int>(startX + image->width(), _width);
int top = tmin<int>(startY + image->height(), _height);
for (int x = left; x < right; x++) {
for (int y = bottom; y < top; y++) {
Rgba color = image->pixelAt(x - left, y - bottom);
drawPoint(x, y, color);
}
}
}
int Raster::size() {
return _width * _height * sizeof (Rgba);
}

2
src/Raster.h

@ -16,6 +16,7 @@
#include "common.h"
#include "Rgba.h"
#include "Image.h"
enum DRAWMODE {
DM_POINTS = 0,
@ -94,6 +95,7 @@ public:
void drawArray(DRAWMODE mode, const float2* points, size_t count);
void drawFilledRect(int startX, int startY, int width, int height);
void drawRect(const int2* points, const Rgba* colors);
void drawImage(int startX, int startY, const Image* image);
int size();
void clean();
bool setPixel(int x, int y, Rgba color);

12
src/Rgba.cc

@ -24,6 +24,10 @@ Rgba::Rgba(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
_a = a;
}
Rgba::Rgba(unsigned int rgba) {
_color = rgba;
}
bool operator==(Rgba &left, Rgba &right) {
return left._a == right._a && left._b == right._b && left._g == right._g && left._r == right._r;
}
@ -35,7 +39,7 @@ bool operator!=(Rgba &left, Rgba &right) {
Rgba::operator unsigned() {
unsigned int ret;
unsigned char* p = (unsigned char*)&ret;
unsigned char* p = (unsigned char*) &ret;
p[0] = _r;
p[1] = _g;
p[2] = _b;
@ -43,14 +47,14 @@ Rgba::operator unsigned() {
//bitset<32> set = ret;
//cout << set << endl;
return ret;
}
Rgba::operator int() {
int ret;
unsigned char* p = (unsigned char*)&ret;
unsigned char* p = (unsigned char*) &ret;
p[0] = _r;
p[1] = _g;
p[2] = _b;
@ -62,7 +66,7 @@ Rgba::operator int() {
Rgba::operator long() {
long ret;
unsigned char* p = (unsigned char*)&ret ;
unsigned char* p = (unsigned char*) &ret;
p[0] = _r;
p[1] = _g;
p[2] = _b;

17
src/Rgba.h

@ -19,16 +19,25 @@
class Rgba {
public:
Rgba(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, unsigned char a = 0);
Rgba(unsigned int rgba);
friend bool operator==(Rgba &left, Rgba &right);
friend bool operator!=(Rgba &left, Rgba &righe);
operator unsigned();
operator int();
operator long();
public:
unsigned char _r;
unsigned char _g;
unsigned char _b;
unsigned char _a;
/*这里使用了联合,可以是类能使用unsigned int 直接赋值*/
union {
struct {
unsigned char _r;
unsigned char _g;
unsigned char _b;
unsigned char _a;
};
unsigned int _color;
};
};
inline Rgba colorLerp(const Rgba& color1, const Rgba& color2, float step) {

71
src/draw_image.cc

@ -0,0 +1,71 @@
#include <iostream>
#include <math.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include "Rgba.h"
#include "Raster.h"
#include "common.h"
#include "Image.h"
using namespace std;
gint height = 500;
gint width = 500;
Raster raster(width, height);
unsigned char* makeBitmap() {
raster.clean();
Image* image = Image::loadFromFile("/home/blobt/Documents/dev/cpp/3dbase/build/bin/12.jpg");
raster.drawImage(25, 25, image);
return (unsigned char*) raster.buffer;
}
void render(GtkWidget *widget) {
//允许窗口可以绘图
gtk_widget_set_app_paintable(widget, TRUE);
gtk_widget_realize(widget);
gtk_widget_queue_draw(widget);
//模拟一张图片
unsigned char* data = makeBitmap();
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
GdkPixmap *pixmap = NULL;
gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 128);
gdk_window_set_back_pixmap(widget->window, pixmap, FALSE);
g_object_unref(pixbuf);
g_object_unref(pixmap);
//delete data;
}
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
//创建窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(window, width, height);
gtk_window_set_title(GTK_WINDOW(window), "Gtk testing");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
//窗口关闭时候,关闭程序
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//设置渲染
g_signal_connect(window, "expose-event", G_CALLBACK(render), window);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Loading…
Cancel
Save