static void rotate_exif(FIBITMAP **dib) { // check for Exif rotation if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, *dib)) { FIBITMAP *rotated = NULL; // process Exif rotation FITAG *tag = NULL; FreeImage_GetMetadata(FIMD_EXIF_MAIN, *dib, "Orientation", &tag); if(tag != NULL) { if(FreeImage_GetTagID(tag) == TAG_ORIENTATION) { unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag)); switch (orientation) { case 1: // "top, left side" => 0° break; case 2: // "top, right side" => flip left-right FreeImage_FlipHorizontal(*dib); break; case 3: // "bottom, right side"; => -180° rotated = FreeImage_Rotate(*dib, 180); FreeImage_Unload(*dib); *dib = rotated; break; case 4: // "bottom, left side" => flip up-down FreeImage_FlipVertical(*dib); break; case 5: // "left side, top" => +90° + flip up-down rotated = FreeImage_Rotate(*dib, 90); FreeImage_Unload(*dib); *dib = rotated; FreeImage_FlipVertical(*dib); break; case 6: // "right side, top" => -90° rotated = FreeImage_Rotate(*dib, -90); FreeImage_Unload(*dib); *dib = rotated; break; case 7: // "right side, bottom" => -90° + flip up-down rotated = FreeImage_Rotate(*dib, -90); FreeImage_Unload(*dib); *dib = rotated; FreeImage_FlipVertical(*dib); break; case 8: // "left side, bottom" => +90° rotated = FreeImage_Rotate(*dib, 90); FreeImage_Unload(*dib); *dib = rotated; break; default: break; } } } } }
BOOL fipImage::rotate(double angle, const void *bkcolor) { if(_dib) { switch(FreeImage_GetImageType(_dib)) { case FIT_BITMAP: switch(FreeImage_GetBPP(_dib)) { case 1: case 8: case 24: case 32: break; default: return FALSE; } break; case FIT_UINT16: case FIT_RGB16: case FIT_RGBA16: case FIT_FLOAT: case FIT_RGBF: case FIT_RGBAF: break; default: return FALSE; break; } FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor); return replace(rotated); } return FALSE; }
/** * Applies a rotation in an angle which is specified as the pAngle parameter. Returns 0 if there is no image loaded or if the rotation fails. * Rotation occurs around the center of the image area. Rotated image * retains size and aspect ratio of source image (destination image size is usually bigger), so * that this function should be used when rotating an image by 90°, 180° or 270°. * @param pAngle Rotation angle. */ bool IND_Image::rotate(double pAngle) { //TODO: MAY NEED ACCESS TO FILLCOLOR WHEN ANGLE IS NOT MULTIPLE OF 90 (BIGGER IMAGE AND BACKGROUND FILLED WITH BLACK COLOR, OPAQUE, BY DEFAULT) // No image loaded if (!isImageLoaded()) return false; FIBITMAP *rotated = FreeImage_Rotate(getFreeImageHandle(), pAngle); // rotation can in some rare circumstances return a NULL value (1-bit images, rotation is limited to angles whose value is an integer multiple of 90°) if (rotated == NULL) return false; //Reset image parameters to new freeimage modified one FreeImage_Unload(getFreeImageHandle()); setFreeImageHandle(rotated); setPointer(FreeImage_GetBits(rotated)); setWidth(FreeImage_GetWidth(rotated)); setHeight(FreeImage_GetHeight(rotated)); return true; }
static struct graphics_image_priv * image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot, int rotation) { #if USE_FREEIMAGE FIBITMAP *image; RGBQUAD aPixel; unsigned char *data; int width, height, i, j; struct graphics_image_priv *gi; //check if image already exists in hashmap struct graphics_image_priv *curr_elem = g_hash_table_lookup(hImageData, path); if (curr_elem == &image_error) { //found but couldn't be loaded return NULL; } else if (curr_elem) { //found and OK -> use hastable entry *w = curr_elem->w; *h = curr_elem->h; hot->x = curr_elem->w / 2 - 1; hot->y = curr_elem->h / 2 - 1; return curr_elem; } else { if (strlen(path) < 4) { g_hash_table_insert(hImageData, g_strdup(path), &image_error); return NULL; } char *ext_str = path + strlen(path) - 3; if (strstr(ext_str, "png") || strstr(path, "PNG")) { if ((image = FreeImage_Load(FIF_PNG, path, 0)) == NULL) { g_hash_table_insert(hImageData, g_strdup(path), &image_error); return NULL; } } else if (strstr(ext_str, "xpm") || strstr(path, "XPM")) { if ((image = FreeImage_Load(FIF_XPM, path, 0)) == NULL) { g_hash_table_insert(hImageData, g_strdup(path), &image_error); return NULL; } } else if (strstr(ext_str, "svg") || strstr(path, "SVG")) { char path_new[256]; snprintf(path_new, strlen(path) - 3, "%s", path); strcat(path_new, "_48_48.png"); if ((image = FreeImage_Load(FIF_PNG, path_new, 0)) == NULL) { g_hash_table_insert(hImageData, g_strdup(path), &image_error); return NULL; } } else { g_hash_table_insert(hImageData, g_strdup(path), &image_error); return NULL; } if (FreeImage_GetBPP(image) == 64) { FIBITMAP *image2; image2 = FreeImage_ConvertTo32Bits(image); FreeImage_Unload(image); image = image2; } #if FREEIMAGE_MAJOR_VERSION*100+FREEIMAGE_MINOR_VERSION >= 313 if (rotation) { FIBITMAP *image2; image2 = FreeImage_Rotate(image, rotation, NULL); image = image2; } #endif gi = g_new0(struct graphics_image_priv, 1); width = FreeImage_GetWidth(image); height = FreeImage_GetHeight(image); if ((*w != width || *h != height) && 0 < *w && 0 < *h) { FIBITMAP *image2; image2 = FreeImage_Rescale(image, *w, *h, NULL); FreeImage_Unload(image); image = image2; width = *w; height = *h; } data = (unsigned char *) malloc(width * height * 4); RGBQUAD *palette = NULL; if (FreeImage_GetBPP(image) == 8) { palette = FreeImage_GetPalette(image); } for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { unsigned char idx; if (FreeImage_GetBPP(image) == 8) { FreeImage_GetPixelIndex(image, j, height - i - 1, &idx); data[4 * width * i + 4 * j + 0] = palette[idx].rgbRed; data[4 * width * i + 4 * j + 1] = palette[idx].rgbGreen; data[4 * width * i + 4 * j + 2] = palette[idx].rgbBlue; data[4 * width * i + 4 * j + 3] = 255; } else if (FreeImage_GetBPP(image) == 16 || FreeImage_GetBPP(image) == 24 || FreeImage_GetBPP(image) == 32) { FreeImage_GetPixelColor(image, j, height - i - 1, &aPixel); int transparent = (aPixel.rgbRed == 0 && aPixel.rgbBlue == 0 && aPixel.rgbGreen == 0); data[4 * width * i + 4 * j + 0] = transparent ? 0 : (aPixel. rgbRed); data[4 * width * i + 4 * j + 1] = (aPixel.rgbGreen); data[4 * width * i + 4 * j + 2] = transparent ? 0 : (aPixel. rgbBlue); data[4 * width * i + 4 * j + 3] = transparent ? 0 : 255; } } } FreeImage_Unload(image); *w = width; *h = height; gi->w = width; gi->h = height; gi->hot_x = width / 2 - 1; gi->hot_y = height / 2 - 1; hot->x = width / 2 - 1; hot->y = height / 2 - 1; gi->data = data; gi->path = path; //add to hashtable g_hash_table_insert(hImageData, g_strdup(path), gi); return gi; } #else return NULL; #endif }
DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateClassic(FIBITMAP *dib, double angle) { return FreeImage_Rotate(dib, angle, NULL); }