1/*******************************************************************************************
2*
3* raylib [textures] example - Image processing
4*
5* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
6*
7* This example has been created using raylib 1.4 (www.raylib.com)
8* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
9*
10* Copyright (c) 2016 Ramon Santamaria (@raysan5)
11*
12********************************************************************************************/
13
14#include "raylib.h"
15
16#include <stdlib.h> // Required for: free()
17
18#define NUM_PROCESSES 8
19
20typedef enum {
21 NONE = 0,
22 COLOR_GRAYSCALE,
23 COLOR_TINT,
24 COLOR_INVERT,
25 COLOR_CONTRAST,
26 COLOR_BRIGHTNESS,
27 FLIP_VERTICAL,
28 FLIP_HORIZONTAL
29} ImageProcess;
30
31static const char *processText[] = {
32 "NO PROCESSING",
33 "COLOR GRAYSCALE",
34 "COLOR TINT",
35 "COLOR INVERT",
36 "COLOR CONTRAST",
37 "COLOR BRIGHTNESS",
38 "FLIP VERTICAL",
39 "FLIP HORIZONTAL"
40};
41
42int main(void)
43{
44 // Initialization
45 //--------------------------------------------------------------------------------------
46 const int screenWidth = 800;
47 const int screenHeight = 450;
48
49 InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing");
50
51 // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
52
53 Image image = LoadImage("resources/parrots.png"); // Loaded in CPU memory (RAM)
54 ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); // Format image to RGBA 32bit (required for texture update) <-- ISSUE
55 Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
56
57 int currentProcess = NONE;
58 bool textureReload = false;
59
60 Rectangle selectRecs[NUM_PROCESSES] = { 0 };
61
62 for (int i = 0; i < NUM_PROCESSES; i++) selectRecs[i] = (Rectangle){ 40.0f, (float)(50 + 32*i), 150.0f, 30.0f };
63
64 SetTargetFPS(60);
65 //---------------------------------------------------------------------------------------
66
67 // Main game loop
68 while (!WindowShouldClose()) // Detect window close button or ESC key
69 {
70 // Update
71 //----------------------------------------------------------------------------------
72 if (IsKeyPressed(KEY_DOWN))
73 {
74 currentProcess++;
75 if (currentProcess > 7) currentProcess = 0;
76 textureReload = true;
77 }
78 else if (IsKeyPressed(KEY_UP))
79 {
80 currentProcess--;
81 if (currentProcess < 0) currentProcess = 7;
82 textureReload = true;
83 }
84
85 if (textureReload)
86 {
87 UnloadImage(image); // Unload current image data
88 image = LoadImage("resources/parrots.png"); // Re-load image data
89
90 // NOTE: Image processing is a costly CPU process to be done every frame,
91 // If image processing is required in a frame-basis, it should be done
92 // with a texture and by shaders
93 switch (currentProcess)
94 {
95 case COLOR_GRAYSCALE: ImageColorGrayscale(&image); break;
96 case COLOR_TINT: ImageColorTint(&image, GREEN); break;
97 case COLOR_INVERT: ImageColorInvert(&image); break;
98 case COLOR_CONTRAST: ImageColorContrast(&image, -40); break;
99 case COLOR_BRIGHTNESS: ImageColorBrightness(&image, -80); break;
100 case FLIP_VERTICAL: ImageFlipVertical(&image); break;
101 case FLIP_HORIZONTAL: ImageFlipHorizontal(&image); break;
102 default: break;
103 }
104
105 Color *pixels = GetImageData(image); // Get pixel data from image (RGBA 32bit)
106 UpdateTexture(texture, pixels); // Update texture with new image data
107 free(pixels); // Unload pixels data from RAM
108
109 textureReload = false;
110 }
111 //----------------------------------------------------------------------------------
112
113 // Draw
114 //----------------------------------------------------------------------------------
115 BeginDrawing();
116
117 ClearBackground(RAYWHITE);
118
119 DrawText("IMAGE PROCESSING:", 40, 30, 10, DARKGRAY);
120
121 // Draw rectangles
122 for (int i = 0; i < NUM_PROCESSES; i++)
123 {
124 DrawRectangleRec(selectRecs[i], (i == currentProcess) ? SKYBLUE : LIGHTGRAY);
125 DrawRectangleLines((int)selectRecs[i].x, (int) selectRecs[i].y, (int) selectRecs[i].width, (int) selectRecs[i].height, (i == currentProcess) ? BLUE : GRAY);
126 DrawText( processText[i], (int)( selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) selectRecs[i].y + 11, 10, (i == currentProcess) ? DARKBLUE : DARKGRAY);
127 }
128
129 DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE);
130 DrawRectangleLines(screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, texture.width, texture.height, BLACK);
131
132 EndDrawing();
133 //----------------------------------------------------------------------------------
134 }
135
136 // De-Initialization
137 //--------------------------------------------------------------------------------------
138 UnloadTexture(texture); // Unload texture from VRAM
139 UnloadImage(image); // Unload image from RAM
140
141 CloseWindow(); // Close window and OpenGL context
142 //--------------------------------------------------------------------------------------
143
144 return 0;
145}