|
Allegro5 Save bitmap to byte array |
Kevin NO
Member #13,410
August 2011
|
Hello everyone, size_t *size = new size_t(); but that is totally wrong. How do I access the byte info inside of ALLEGRO_FILE? |
beoran
Member #12,636
March 2011
|
You will need to use the memfile addon and al_open_memfile() |
Kevin NO
Member #13,410
August 2011
|
Thanks for the quick reply! I am trying to use the memfile, here is what I have: SubBmp = al_create_sub_bitmap(World, x, y, 16, 16); data_size = al_get_bitmap_width(SubBmp) * al_get_bitmap_height(SubBmp) * al_get_pixel_size(al_get_bitmap_format(SubBmp)); //Test if buffer has bitmap array al_fclose(memfile); Still nothing in the buffer, or at lest i don't think there is. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
I wouldn't do it quite that way. It would be easier to lock the bitmap and read the data directly. Ex : 1unsigned char* BitmapBytes(ALLEGRO_BITMAP* bmp , int* size_store) {
2 int size = al_get_bitmap_width(bmp)*al_get_bitmap_height(bmp)*4;
3 unsigned char* buffer = malloc(size);
4 if (buffer) {
5 *size_store = size;
6 } else {
7 *size_store = 0;
8 return 0;
9 }
10
11 ALLEGRO_LOCKED_REGION* lock = al_lock_bitmap(bmp , ALLEGRO_PIXEL_FORMAT_RGBA_8888 , ALLEGRO_LOCK_READONLY);
12
13 for (unsigned int y = 0 ; y < al_get_bitmap_height(bmp) ; ++y) {
14 unsigned char* dat = (unsigned char*)lock->data + 4*y*lock->pitch;
15 memcpy(buffer + 4*y*al_get_bitmap_width(bmp) , dat , 4*al_get_bitmap_width(bmp));
16 }
17
18 al_unlock_bitmap(bmp);
19
20 return buffer;
21}
Untested, but you get the idea. The bitmap is locked using RGBA_8888 (allegro will perform necessary conversions for you), and then a simple memcpy copies the memory into the newly allocated buffer and the function returns the buffer and stores the size in the int pointer provided to the function. You can use <code>code goes here...</code> tags to show your code. Makes it easier to read. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Thomas Fjellstrom
Member #476
June 2000
|
Edgar Reynaldo said: Untested, but you get the idea. The bitmap is locked using RGBA_8888 (allegro will perform necessary conversions for you), and then a simple memcpy copies the memory into the newly allocated buffer and the function returns the buffer and stores the size in the int pointer provided to the function. Depends if he wants the actual bitmap headers or not. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Well, in that case I would just save the bitmap to a temporary file on the hard drive and not mess around with a memfile. It would be much easier to get a fix on the actual size of the bitmap file. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Thomas Fjellstrom
Member #476
June 2000
|
Depends if he wants it to hit the disk or not -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
The point I was trying to make is that he has to know the exact layout of the file if he wants the headers and he is going to use a memfile, otherwise he doesn't know the exact size of the buffer he needs. That's why I suggested saving to disk. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
beoran
Member #12,636
March 2011
|
In the code above, where does buffer come from? you shoyld use data to initailze the memfile and save that, I think. Also , you seem to draw to the wrong bitmap. It's hard to say without the complete code. Could you psot a complete, compilable example of what you're trying to do? |
Kevin NO
Member #13,410
August 2011
|
Hello, What I am trying to do is read a Large bitmap into a database. 1/*
2#include <stdio.h>
3#ifdef _MSC_VER
4#pragma comment ( linker, "/SUBSYSTEM:CONSOLE")
5#endif #define ALLEGRO_USE_CONSOLE
6#include <allegro5/allegro.h>
7#include <allegro5/allegro_memfile.h>
8
9int main(void)
10{
11 ALLEGRO_FILE *memfile;
12 char *data;
13 int i;
14 const int data_size = 1024;
15 char buffer[50];
16 if (!al_init())
17 {
18 //abort_example("Could not init Allegro.\n");
19 }
20 data = (char*)calloc(1, data_size);
21 if (!data) return 1;
22 printf("Creating memfile\n");
23 memfile = al_open_memfile(data, data_size, "rw");
24 if (!memfile)
25 {
26 printf("Error opening memfile :(\n");
27 goto Error;
28 }
29 printf("Writing data to memfile\n");
30 for (i = 0; i < data_size/4; i++)
31 {
32 if (al_fwrite32le(memfile, i) < 4)
33 {
34 printf("Failed to write %i to memfile\n", i);
35 goto Error;
36 }
37 }
38 al_fseek(memfile, 0, ALLEGRO_SEEK_SET);
39 printf("Reading and testing data from memfile\n");
40 for (i = 0; i < data_size/4; i++)
41 {
42 int32_t ret = al_fread32le(memfile);
43 if (ret != i || al_feof(memfile))
44 {
45 printf("Item %i failed to verify, got %i\n", i, ret);
46 goto Error;
47 }
48 }
49 if (al_feof(memfile))
50 {
51 printf("EOF indicator prematurely set!\n");
52 goto Error;
53 }
54 al_fseek(memfile, 0, ALLEGRO_SEEK_SET);
55 for (i = 0; al_fungetc(memfile, i) != EOF; ++i) { }
56 printf("Length of ungetc buffer: %d\n", i);
57 if (al_ftell(memfile) != -i)
58 {
59 printf("Current position is not correct. Expected -%d, but got %d\n", i, (int) al_ftell(memfile));
60 goto Error;
61 }
62 while (i--)
63 {
64 if (i != al_fgetc(memfile))
65 {
66 printf("Failed to verify ungetc data.\n");
67 goto Error;
68 }
69 }
70 if (al_ftell(memfile) != 0)
71 {
72 printf("Current position is not correct after reading back the ungetc buffer\n");
73 printf("Expected 0, but got %d\n", (int) al_ftell(memfile));
74 goto Error;
75 }
76 al_fputs(memfile, "legro rocks!");
77 al_fseek(memfile, 0, ALLEGRO_SEEK_SET);
78 al_fungetc(memfile, 'l');
79 al_fungetc(memfile, 'A');
80 al_fgets(memfile, buffer, 15);
81 if (strcmp(buffer, "Allegro rocks!"))
82 {
83 printf("Expected to see 'Allegro rocks!' but got '%s' instead.\n", buffer);
84 printf("(Maybe the ungetc buffer isn't big enough.)\n");
85 goto Error;
86 }
87 printf("Done.\n");
88 al_fclose(memfile);
89 free(data);
90 return 0;
91Error:
92 al_fclose(memfile);
93 free(data);
94 return 1;
95}*/
96
97#pragma region MyRegion
98#include <stdio.h>
99#include <vector>
100#include <string>
101#include "sqlite3.h"
102#include <allegro5/allegro.h>
103#include <allegro5/allegro_font.h>
104#include <allegro5/allegro_ttf.h>
105#include <allegro5/allegro_image.h>
106#include <allegro5/allegro_memfile.h>
107#include "allegro5/allegro_native_dialog.h"
108#include <fstream>
109
110
111
112static int callback(void *NotUsed, int argc, char **argv, char **azColName){
113 int i;
114 for(i=0; i<argc; i++){
115 printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
116 }
117 printf("\n");
118 return 0;
119}
120
121unsigned char* BitmapBytes(ALLEGRO_BITMAP* bmp , int* size_store)
122{
123 int size = al_get_bitmap_width(bmp)*al_get_bitmap_height(bmp)*4;
124 unsigned char* buffer = (unsigned char*)malloc(size);
125 if (buffer)
126 {
127 *size_store = size;
128 }
129 else
130 {
131 *size_store = 0;
132 return 0;
133 }
134 ALLEGRO_LOCKED_REGION* lock = al_lock_bitmap(bmp , ALLEGRO_PIXEL_FORMAT_RGBA_8888 , ALLEGRO_LOCK_READONLY);
135 for (unsigned int y = 0 ; y < al_get_bitmap_height(bmp); ++y)
136 {
137 unsigned char* dat = (unsigned char*)lock->data + 4*y*lock->pitch;
138 memcpy(buffer + 4*y*al_get_bitmap_width(bmp) , dat , 4*al_get_bitmap_width(bmp));
139 }
140 al_unlock_bitmap(bmp);
141 return buffer;
142}
143
144int main(int argc, char **argv){
145
146 al_init();
147 al_init_image_addon();
148 al_init_font_addon();
149 al_init_ttf_addon();
150
151 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
152 event_queue = al_create_event_queue();
153
154 std::vector<ALLEGRO_BITMAP*> Bitmaps;
155
156 ALLEGRO_DISPLAY *display = al_create_display(640,480);
157 al_register_event_source(event_queue, al_get_display_event_source(display));
158 ALLEGRO_FONT *font = al_load_ttf_font("C:\\Users\\Kevin\\Desktop\\Programing\\BitmapToSqliteConverter\\Debug\\arial.ttf",24,0 );
159
160 //al_clear_to_color(al_map_rgb(50,10,70));
161
162
163
164 ALLEGRO_BITMAP* World = NULL;
165 World = al_load_bitmap("C:/Users/Kevin/Desktop/Programing/BitmapToSqliteConverter/Debug/Island.bmp");
166 if(!World) {
167 printf("Error loading hello.bmp\n");
168 return 1;
169 }
170
171 sqlite3 *db;
172 char *zErrMsg = 0;
173 int rc;
174 rc = sqlite3_open("C:\\Users\\Kevin\\Desktop\\Programing\\mov\\movDB", &db);
175 /* Open database */
176 if( rc ){
177 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
178 exit(0);
179 }else{
180 fprintf(stderr, "Opened database successfully\n");
181 }
182 const char* sql;
183
184 char fileName[10];
185 int count = 0;
186
187 ALLEGRO_FILE *memfile;
188 ALLEGRO_BITMAP *SubBmp;
189 char data[5];
190 int data_size;
191 unsigned char *buffer;
192
193 void *fileBuffer;
194 void *graphicBuffer;
195 int length = 16;
196
197 for (int y = 10; y < al_get_bitmap_height(World); y = y + 16)
198 {
199 for (int x = 0; x < al_get_bitmap_width(World); x = x + 16)
200 {
201 SubBmp = al_create_sub_bitmap(World, x, y, 16, 16);
202 //buffer = BitmapBytes(SubBmp, &length);
203 count++;
204 itoa(count,data,10);
205 al_save_bitmap(strcat(data,".bmp"),SubBmp);
206
207 }
208 }
209 return 0;
210}
211#pragma endregion
|
beoran
Member #12,636
March 2011
|
Hmmm, your coee seems to be missing the point. I have attached an example that cuts up a bitmap and saves it to files using the memfile addon. However, I think you could adapt without too much effort to saving to sqlite using the real_size and buffer. Here is the code repeated: 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_memfile.h>
3#include <stdio.h>
4#include <stdlib.h>
5
6
7#define DISPLAY_W 640
8#define DISPLAY_H 480
9
10#define SKIP_W 16
11#define SKIP_H 16
12
13void display_bitmap(ALLEGRO_BITMAP * bmp, int x, int y, double delay) {
14 al_clear_to_color(al_map_rgb(0, 0, 0));
15 al_draw_bitmap(bmp, (double)x, (double)y, 0);
16 al_flip_display();
17 al_rest(delay);
18}
19
20bool save_sub_bitmap(ALLEGRO_BITMAP * sub,
21 int x, int y, int slice_w, int slice_h,
22 const char * prefix) {
23 int size;
24 void * buffer;
25 int real_size;
26 ALLEGRO_FILE * memfile;
27
28 if(!sub) {
29 fprintf(stderr, "Could not create sub bitmap!\n");
30 return false;
31 }
32 /* Allocate a buffer that should always be too big.*/
33 size = slice_w * slice_h * 4 * 2;
34 buffer = calloc(size, 1);
35 real_size = 0;
36 if(!buffer) {
37 fprintf(stderr, "Could not allocate buffer!\n");
38 return false;
39 }
40
41 /* Open memfile. */
42 memfile = al_open_memfile(buffer, size, "rw");
43 if(!memfile) {
44 fprintf(stderr, "Failed to open memfile!\n");
45 } else {
46 /* save the bitmap into the memfile. */
47 al_save_bitmap_f(memfile, ".bmp", sub);
48 /* Get the real size of the bitmap. */
49 real_size = al_ftell(memfile);
50 if(real_size < 1) {
51 fprintf(stderr, "Real size is too small!\n");
52 } else {
53 /* now, buffer contains the correct bitmap data. Save that to a file
54 * (but if could be stored into sqlite as well, if needed). */
55 FILE * output;
56 char filename[255];
57 sprintf(filename, "%.16s_%d_%d.bmp\0", prefix, (int)(x / slice_w) + 1, (int)(y/slice_h) + 1);
58 output = fopen(filename, "w");
59 if(!output) {
60 fprintf(stderr, "Could not open output file!\n");
61 } else {
62 fwrite(buffer, size, 1, output);
63 fclose(output);
64 }
65 }
66 al_fclose(memfile);
67 }
68 free(buffer);
69}
70
71
72bool split_and_save_bitmap(ALLEGRO_BITMAP * input, int slice_w, int slice_h, const char * prefix) {
73 int x, y;
74 for(y = 0; y < al_get_bitmap_height(input) ; y += slice_h) {
75 for(x = 0; x < al_get_bitmap_width(input) ; x += slice_w) {
76 /* create the sub bitmap */
77 ALLEGRO_BITMAP * sub = al_create_sub_bitmap(input, x, y, slice_w, slice_h);
78 /* display it, then save it, and then clean up. */
79 display_bitmap(sub, x, y, 0.1);
80 save_sub_bitmap(sub, x, y, slice_w, slice_h, prefix);
81 al_destroy_bitmap(sub);
82 }
83 }
84
85}
86
87
88int main(int argc, char ** argv) {
89 ALLEGRO_DISPLAY * display = NULL;
90 ALLEGRO_BITMAP * input = NULL;
91
92 if (!al_init()) {
93 fprintf(stderr, "Failed to initialize allegro!\n");
94 return 1;
95 }
96
97 if (!al_init_image_addon()) {
98 fprintf(stderr, "Failed to initialize image addon!\n");
99 return 2;
100 }
101
102 display = al_create_display(DISPLAY_W, DISPLAY_H);
103 if(!display) {
104 fprintf(stderr, "Failed to create display!\n");
105 return 3;
106 }
107
108 input = al_load_bitmap("input.png");
109 if (!input) {
110 fprintf(stderr, "Failed to load input!\n");
111 al_destroy_display(display);
112 return 4;
113 }
114 /* Display loaded bitmap */
115 display_bitmap(input, 0.0, 0.0, 0.5);
116 /* Now split and save it. */
117 split_and_save_bitmap(input, SKIP_W, SKIP_H, "output");
118
119 al_destroy_display(display);
120}
Oh and here is an example of how to save a binary blob, which would be a bitmap file in your case, using sqlite3 http://www.sqlite.org/cvstrac/wiki?p=BlobExample |
|