void render (gint32 image_ID, GimpDrawable *drawable, PlugInVals *vals, PlugInImageVals *image_vals, PlugInDrawableVals *drawable_vals) { double angle = gimp_find_skew(drawable); // in radians DEBUGPRINT("deskew: angle=%.2f\n", 57.295779513082320876798154814105*angle); if (fabs(angle) < deskew_threshold) { // nothing to do; already straightened. return; } gimp_context_push (); gimp_context_set_interpolation (GIMP_INTERPOLATION_CUBIC); gimp_context_set_transform_resize (GIMP_TRANSFORM_RESIZE_ADJUST); drawable->drawable_id = gimp_item_transform_rotate(drawable->drawable_id, angle, TRUE, // auto_center -1, -1 // center_x, center_y ); gimp_context_pop (); }
/* ----------------------------------- * p_exact_align_drawable * ----------------------------------- * 4-point alignment including necessary scale and rotate transformation * to match 2 pairs of corresponding coordonates. */ static gint32 p_exact_align_drawable(gint32 activeDrawableId, AlingCoords *alingCoords) { gdouble px1, py1, px2, py2; gdouble px3, py3, px4, py4; gdouble dx1, dy1, dx2, dy2; gdouble angle1Rad, angle2Rad, angleRad; gdouble len1, len2; gdouble scaleXY; gint32 transformedDrawableId; px1 = alingCoords->startCoords.px; py1 = alingCoords->startCoords.py; px2 = alingCoords->startCoords2.px; py2 = alingCoords->startCoords2.py; px3 = alingCoords->currCoords.px; py3 = alingCoords->currCoords.py; px4 = alingCoords->currCoords2.px; py4 = alingCoords->currCoords2.py; dx1 = px2 - px1; dy1 = py2 - py1; dx2 = px4 - px3; dy2 = py4 - py3; /* the angle between the two lines. i.e., the angle layer2 must be clockwise rotated * in order to overlap with initial start layer1 */ angle1Rad = 0; angle2Rad = 0; if (dx1 != 0.0) { angle1Rad = atan(dy1 / dx1); } if (dx2 != 0.0) { angle2Rad = atan(dy2 / dx2); } angleRad = angle1Rad - angle2Rad; /* the scale factors current layer must be mulitplied by, * in order to fit onto reference start layer. * this is simply the ratio of the two line lenths from the path we created with the 4 points */ len1 = sqrt((dx1 * dx1) + (dy1 * dy1)); len2 = sqrt((dx2 * dx2) + (dy2 * dy2)); scaleXY = 1.0; if ((len1 != len2) && (len2 != 0.0)) { scaleXY = len1 / len2; } gimp_context_set_defaults(); gimp_context_set_transform_resize(GIMP_TRANSFORM_RESIZE_ADJUST); /* do NOT clip */ gimp_context_set_transform_direction(GIMP_TRANSFORM_FORWARD); transformedDrawableId = gimp_item_transform_2d(activeDrawableId , px3 , py3 , scaleXY , scaleXY , angleRad , px1 , py1 ); if(gap_debug) { printf("p_exact_align_drawable: activeDrawableId:%d transformedDrawableId:%d\n" " p1: %f %f\n" " p2: %f %f\n" " p3: %f %f\n" " p4: %f %f\n" " scale:%f angleRad:%f (degree:%f)\n" ,(int)activeDrawableId ,(int)transformedDrawableId ,(float)px1 ,(float)py1 ,(float)px2 ,(float)py2 ,(float)px3 ,(float)py3 ,(float)px4 ,(float)py4 ,(float)scaleXY ,(float)angleRad ,(float)(angleRad * 180.0) / G_PI ); } return (transformedDrawableId); } /* end p_exact_align_drawable */