int Image::load(std::string filepath) { /* validate */ if (0 == filepath.size()) { RX_ERROR("Error: empty filepath.\n"); return -1; } if (false == rx_file_exists(filepath)) { RX_ERROR("File doesn't exist.\n"); return -2; } std::string ext = rx_get_file_ext(filepath); if (ext == "jpg") { type = IMAGE_JPEG; } else if(ext == "png") { type = IMAGE_PNG; } else { RX_ERROR("Unknown extension: %s\n", ext.c_str()); return -3; } if (type == IMAGE_PNG) { if (!rx_load_png(filepath, &pixels, width, height, channels, &capacity)) { RX_ERROR("Cannot load png: %s", filepath.c_str()); return -4; } } else if(type == IMAGE_JPEG) { if (!rx_load_jpg(filepath, &pixels, width, height, channels, &capacity)) { RX_ERROR("Cannot load jpg: %s", filepath.c_str()); return -5; } } else { RX_ERROR("Invald image type (shouldn't happen)."); return -6; } RX_VERBOSE("Loaded: %s, allocated: %d bytes", filepath.c_str(), capacity); return 0; }
bool Image::load(std::string filename, bool datapath) { if(pixels) { deallocate(); } std::string ext = rx_get_file_ext(filename); if(ext == "png") { return rx_load_png(*this, filename, datapath); } else if(ext == "jpg") { return rx_load_jpg(*this, filename, datapath); } else if(ext == "tga") { return rx_load_tga(*this, filename, datapath); } else { RX_ERROR(ERR_IMG_UNSUPPORTED_EXT); return false; } return false; }
int main(int argc, char** argv) { int c; float col_r, col_g, col_b = -1.0f; Options opt; while ((c = getopt(argc, argv, "a:x:y:f:s:t:n:w:r:g:b:c:h:i:j:o:v")) != -1) { switch(c) { /* verbose */ /* ------------------------------------------------------- */ case 'v': { opt.verbose = 0; break; } /* color */ /* ------------------------------------------------------- */ case 'r': { col_r = convert_type<float>(optarg); break; } case 'g': { col_g = convert_type<float>(optarg); break; } case 'b': { col_b = convert_type<float>(optarg); break; } /* ------------------------------------------------------- */ /* hashtag */ case 'h': { opt.hashtag = convert_type<std::string>(optarg); break; } case 'i': { opt.hashtag_x = convert_type<int>(optarg); break; } case 'j': { opt.hashtag_y = convert_type<int>(optarg); break; } /* ------------------------------------------------------- */ /* foreground */ case 'c': { opt.foreground_file = convert_type<std::string>(optarg); break; } /* ------------------------------------------------------- */ /* background */ case 'x': { opt.background_x = convert_type<int>(optarg); break; } case 'y': { opt.background_y = convert_type<int>(optarg); break; } case 'f': { opt.background_file = convert_type<std::string>(optarg); break; } /* ------------------------------------------------------- */ /* visible size */ case 'a': { opt.visible_size = convert_type<float>(optarg); break; } /* ------------------------------------------------------- */ /* output */ case 'o': { opt.output_file = convert_type<std::string>(optarg); break; } /* ------------------------------------------------------- */ /* name */ case 'n': { opt.name = convert_type<std::string>(optarg); /* we expect that r,g,b has been set */ if (0 > col_r) { printf("Error: you haven't set -r -g -b for the name.\n"); exit(EXIT_FAILURE); } opt.name_r = col_r; opt.name_g = col_g; opt.name_b = col_b; break; } /* name x position */ case 's': { opt.name_x = convert_type<int>(optarg); break; } /* name y position */ case 't': { opt.name_y = convert_type<int>(optarg); break; } /* name font size */ case 'w': { opt.name_font_size = convert_type<float>(optarg); break; } default: { printf("Unkown option\n"); break; } } } if (false == opt.validate()) { printf("+ error: cannot validate the given options.\n"); exit(EXIT_FAILURE); } opt.print(); /* ------------------------------------------------------------------------------------ */ Image img; std::string path; std::string ext; cairo_surface_t* surf_bg = NULL; cairo_format_t img_format = CAIRO_FORMAT_INVALID; path = opt.foreground_file; if (false == rx_file_exists(path)) { printf("+ error: cannot find the file: %s\n", path.c_str()); exit(EXIT_FAILURE); } cairo_surface_t* surf_overlay = cairo_image_surface_create_from_png(path.c_str()); if (NULL == surf_overlay) { printf("Error: cannot create s1\n"); exit(EXIT_FAILURE); } path = opt.background_file; if (false == rx_file_exists(path)) { printf("Error: file doesn't exist: %s\n", path.c_str()); exit(EXIT_FAILURE); } /* check what file type was given. */ ext = rx_get_file_ext(path); if (ext == "jpg") { printf("+ warning: jpg as input doesn't seem to work\n"); /* cairo doesn't have support for PNG? */ if (0 > rx_load_jpg(path, &img.pixels, img.width, img.height, img.channels)) { printf("Error: failed to load: %s\n", path.c_str()); exit(EXIT_FAILURE); } if (0 == img.width || 0 == img.height || 0 == img.channels) { printf("Error: image has invalid flags: %d x %d, channels: %d\n", img.width, img.height, img.channels); exit(EXIT_FAILURE); } if (3 == img.channels) { img_format = CAIRO_FORMAT_RGB24; printf("+ Using RGB24\n"); } else if(4 == img.channels) { img_format = CAIRO_FORMAT_ARGB32; printf("+ Using ARGB32\n"); } else { printf("Error: unsupported number of channels: %d.\n", img.channels); exit(EXIT_FAILURE); } if (NULL != img.pixels && NULL == surf_bg) { printf("Stride: %d\n", cairo_format_stride_for_width(img_format, img.width)); printf("Info: creating %d x %d, channels: %d\n", img.width, img.height, img.channels); surf_bg = cairo_image_surface_create_for_data(img.pixels, img_format, img.width, img.height, cairo_format_stride_for_width(img_format, img.width)); #if 0 /* TESTING */ cairo_t* cr = cairo_create(surf_bg); if (NULL == cr) { printf("Error: cannot create the cairo"); exit(EXIT_FAILURE); } path = rx_get_exe_path() +"/generated_polaroid.png"; cairo_surface_write_to_png(surf_bg, path.c_str()); printf("Created\n"); exit(0); /* END TESTING */ #endif } } else if (ext == "png") { /* use cairo png load feature. */ surf_bg = cairo_image_surface_create_from_png(path.c_str()); if (NULL == surf_bg) { printf("Error: cannot create s2\n"); exit(EXIT_FAILURE); } } else { printf("Error: unsupported file format: %s\n", ext.c_str()); exit(EXIT_FAILURE); } /* make sure the background is loaded correctly (aka the photo) */ if (NULL == surf_bg) { printf("Error: cannot create background surface.\n"); exit(EXIT_FAILURE); } if (CAIRO_STATUS_SUCCESS != cairo_surface_status(surf_bg)) { printf("Error: something went wrong: %d\n", cairo_surface_status(surf_bg)); exit(EXIT_FAILURE); } float source_width = cairo_image_surface_get_width(surf_bg); float source_height = cairo_image_surface_get_height(surf_bg); /* create output */ int dest_width = cairo_image_surface_get_width(surf_overlay); int dest_height = cairo_image_surface_get_height(surf_overlay); if (0 == opt.verbose) { printf("+ Output size: %d x %d\n", dest_width, dest_height); } cairo_surface_t* surf_out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dest_width, dest_height); if (NULL == surf_out) { printf("Error: cannot create cairo_surface_t\n"); exit(EXIT_FAILURE); } if (0 == opt.verbose) { printf("+ Info: creating output surface: %d x %d\n", dest_width, dest_height); } cairo_t* cr = cairo_create(surf_out); if (NULL == cr) { printf("Error: cannot create the cairo"); exit(EXIT_FAILURE); } float scale_factor = opt.visible_size / source_width; if (0 == opt.verbose) { printf("+ Scale factor: %f\n", scale_factor); } /* paint background */ cairo_save(cr); cairo_scale(cr, scale_factor, scale_factor); cairo_set_source_surface(cr, surf_bg, opt.background_x, opt.background_y); cairo_rectangle(cr, 0, 0, img.width, img.height); cairo_paint(cr); cairo_restore(cr); /* paint overlay */ cairo_set_source_surface(cr, surf_overlay, 0, 0); cairo_paint(cr); cairo_surface_flush(surf_out); /* font settings. */ cairo_font_options_t* font_options = cairo_font_options_create(); if (NULL == font_options) { printf("+ Error: cannot create font options. Cannot create polaroid.\n"); exit(EXIT_FAILURE); } cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_BEST); cairo_font_options_set_hint_metrics(font_options, CAIRO_HINT_METRICS_DEFAULT); cairo_set_font_options (cr, font_options); cairo_select_font_face(cr, "Platform", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_source_rgba(cr, opt.name_r, opt.name_g, opt.name_b, 1.0); /* name */ if (0 != opt.name.size()) { cairo_move_to(cr, opt.name_x, opt.name_y); cairo_set_font_size(cr, opt.name_font_size); cairo_show_text(cr, opt.name.c_str()); cairo_stroke(cr); cairo_fill(cr); } /* hashtag */ if (0 != opt.hashtag.size()) { cairo_select_font_face(cr, "Platform", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_move_to(cr, opt.hashtag_x, opt.hashtag_y); cairo_set_font_size(cr, opt.name_font_size); cairo_show_text(cr, opt.hashtag.c_str()); cairo_stroke(cr); cairo_fill(cr); } cairo_surface_flush(surf_out); /* write out */ path = opt.output_file; cairo_surface_write_to_png(surf_out, path.c_str()); /* cleanup */ cairo_surface_destroy(surf_out); cairo_surface_destroy(surf_bg); cairo_surface_destroy(surf_overlay); cairo_destroy(cr); if (0 == opt.verbose) { printf("\n"); } return 0; }