コード例 #1
0
ファイル: imagemagick.py プロジェクト: PixelGordo/HQ-Tools
def _cnv_reduce(po_src_file, po_dst_file, po_cfg):
    """
    Simple function to resize an image while respecting it's original aspect ratio.
    :param po_src_file:
    :param po_dst_file:
    :type po_cfg ImgConvertCfg:
    :return:
    """

    # TODO: Think about something interesting to do with the options -o float,float

    # Variables preparation for imagemagick command
    # ----------------------------------------------
    ti_img_src_size = _img_get_size(po_src_file.u_path)
    ti_img_dst_size = geom.max_rect_in(ptf_rec_out=po_cfg.ti_size, ptf_asp_in=po_cfg.tf_aspect)

    # Command line build
    #-------------------
    u_cmd = u'convert '
    u_cmd += u'"%s" ' % cmd.sanitize_path(po_src_file.u_path)

    # Background
    u_cmd += u'-background "#%s" ' % po_cfg.u_color

    # Resize
    if ti_img_src_size[0] > ti_img_dst_size[0] and ti_img_src_size[1] > ti_img_dst_size[1]:
        u_cmd += u'-resize %ix%i! ' % (ti_img_dst_size[0], ti_img_dst_size[1])

    # Rotation
    u_cmd += u'-rotate %f +repage ' % po_cfg.f_rotation

    # Final output
    u_cmd += u'"%s"' % cmd.sanitize_path(po_dst_file.u_path)

    # Command line execution
    #-----------------------
    du_output = cmd.execute(u_cmd)

    if du_output['u_stderr']:
        print du_output['u_stderr']

    # Coordinates calculation after image manipulation
    #-------------------------------------------------
    o_img_transformation = ImgKeyCoords()
    o_img_transformation.ti_size = _img_get_size(po_dst_file.u_path)

    # Debug code to overlay image regions
    #_draw_coordinates(po_dst_file, o_img_transformation)

    return o_img_transformation
コード例 #2
0
ファイル: imagemagick.py プロジェクト: PixelGordo/HQ-Tools
def _cnv_magcover(po_src_file, po_dst_file, po_cfg):
    """
    :param po_src_file:
    :param po_dst_file:
    :param po_cfg:
    :return:
    """

    # Media preparation
    #------------------
    o_img_corner_fold = files.FilePath(o_MEDIA_ROOT_FP.u_path, u'magcover', u'corner_fold.png')
    o_img_corner_fold.absfile()
    u_img_corner_fold = o_img_corner_fold.u_path.decode('utf8')

    o_img_left_brightness = files.FilePath(o_MEDIA_ROOT_FP.u_path, u'magcover', u'left_brightness.png')
    o_img_left_brightness.absfile()
    u_img_left_brightness = o_img_left_brightness.u_path.decode('utf8')

    o_img_left_fold = files.FilePath(o_MEDIA_ROOT_FP.u_path, u'magcover', u'left_fold_dark.png')
    o_img_left_fold.absfile()
    u_img_left_fold = o_img_left_fold.u_path.decode('utf8')

    o_img_stp = files.FilePath(o_MEDIA_ROOT_FP.u_path, u'magcover', u'staple.png')
    o_img_stp.absfile()
    u_img_stp = o_img_stp.u_path.decode('utf8')

    # Trigonometric pre-calculations
    #-------------------------------
    f_sin = math.sin(math.radians(po_cfg.f_rotation))
    f_cos = math.cos(math.radians(po_cfg.f_rotation))

    # Variables preparation
    #----------------------
    ti_cvr_size_final = geom.max_rect_in(po_cfg.ti_size, po_cfg.tf_aspect)

    # Staples
    ti_stp_size_orig = _img_get_size(u_img_stp)
    f_stp_pos_ratio = 0.049 * ti_cvr_size_final[0] / ti_cvr_size_final[1] + 0.220  # based in my quick statistical study
    f_stp_paper_y_ratio = 0.043 * 2                                                # TODO: Use statistical study again

    _i_stp_height = int(f_stp_paper_y_ratio * ti_cvr_size_final[1])
    ti_stp_size_final = (int(1.0 * ti_stp_size_orig[0] * _i_stp_height / ti_stp_size_orig[1]),
                         _i_stp_height)
    i_stp_x = int(11.0 / 60.0 * ti_stp_size_final[0])

    # Landscape covers will have just one staple while portrait ones will have 2
    li_staples_y = []
    if float(ti_cvr_size_final[0]) / ti_cvr_size_final[1] > 1.0:
        li_staples_y.append(0.5 * ti_cvr_size_final[1] - 0.5 * _i_stp_height)
    else:
        li_staples_y.append(f_stp_pos_ratio * ti_cvr_size_final[1] - 0.5 * _i_stp_height)
        li_staples_y.append((1 - f_stp_pos_ratio) * ti_cvr_size_final[1] - 0.5 * _i_stp_height)

    # Left fold configuration
    i_fold_size = math.ceil(0.025 * ti_cvr_size_final[0])
    f_fold_mult = 0.5

    # Shadow configuration
    i_shadow1_dist = math.ceil(0.01 * min(po_cfg.ti_size))
    i_shadow1_opac = 70                                                                    # 0-100
    i_shadow1_blur = math.ceil(0.0025 * max(po_cfg.ti_size))

    i_shadow2_blur = 4 * i_shadow1_blur

    # Left Brightness configuration
    f_left_bright_mult = 0.5 * (1 + abs(f_sin))                                            # 0.5 at 90º, 1.0 at 0º

    # Corner fold configuration
    f_bottom_right_bright_mult = 0.1 * (1 + max(0, math.cos(math.radians(45 + po_cfg.f_rotation))))
    i_corner_fold_size_final = int(0.06 * ti_cvr_size_final[0])

    # Command line build
    #-------------------
    u_cmd = u'convert '
    u_cmd += u'"%s" ' % cmd.sanitize_path(po_src_file.u_path)                              # Source file
    u_cmd += u'-resize %ix%i! ' % (ti_cvr_size_final[0], ti_cvr_size_final[1])             # Resizing
    u_cmd += u'-background transparent '                                                   # Transparent background

    # Left fold
    # TODO: Make left fold shadow transitions to a left fold brightness for high rotation angles (>45º)
    u_cmd += u'\( "%s" ' % u_img_left_fold
    u_cmd += u'-fill Black -colorize 100%%,100%%,100%%,0%% '
    u_cmd += u'-resize %ix%i! ' % (i_fold_size, ti_cvr_size_final[1])
    u_cmd += u'-channel alpha -fx "%s * a" ' % f_fold_mult                                 # Alpha channel modification
    u_cmd += u'-gravity NorthWest -extent %ix0 ' % ti_cvr_size_final[0]
    u_cmd += u'-background "#808080" -flatten -background transparent '
    u_cmd += u'\) -compose hardlight -composite '

    # Left reflection
    # TODO: Make reflection intensity (and shape?) change with rotation angle.
    u_cmd += u'\( "%s" ' % cmd.sanitize_path(u_img_left_brightness)                                           # Left brightness
    u_cmd += u'-resize %ix%i! ' % (ti_cvr_size_final[0], ti_cvr_size_final[1])             # Light add
    u_cmd += u'-channel alpha -fx "%s * a" ' % f_left_bright_mult                          # Alpha channel modification
    u_cmd += u'\) -composite '

    # Bottom right corner fold reflection
    u_cmd += u'-gravity SouthEast '
    u_cmd += u'\( "%s" ' % cmd.sanitize_path(u_img_corner_fold)
    u_cmd += u'-resize %ix%i! ' % (i_corner_fold_size_final, i_corner_fold_size_final)
    u_cmd += u'-channel alpha -fx "%s * a" ' % f_bottom_right_bright_mult
    u_cmd += u'\) -composite '
    u_cmd += u'-gravity NorthWest '

    # Staples
    u_cmd += u'-gravity east -extent +%i+0 -gravity northwest ' % i_stp_x
    for i_staple_y in li_staples_y:
        u_cmd += u'\( "%s" ' % cmd.sanitize_path(u_img_stp)
        u_cmd += u'-resize x%i ' % _i_stp_height
        u_cmd += u'-geometry +0+%i ' % i_staple_y
        u_cmd += u'\) -compose over -composite '

    u_cmd += u'-rotate %f ' % po_cfg.f_rotation

    # Primary shadow
    u_cmd += u'\( '
    u_cmd += u'-clone 0 -background black '
    u_cmd += u'-resize 100%% '
    u_cmd += u'-shadow %ix%i+0+%i ' % (i_shadow1_opac, i_shadow1_blur, i_shadow1_dist)
    u_cmd += u'\) '

    # Secondary shadow
    u_cmd += u'\( '
    u_cmd += u'-clone 0 -background black '
    u_cmd += u'-shadow 40x%i+0+0 ' % i_shadow2_blur
    u_cmd += u'\) '

    u_cmd += u'-reverse -background none -layers merge +repage '                         # Shadow composition

    u_cmd += u'-background "#%s" -flatten ' % po_cfg.u_color                             # Background color
    u_cmd += u'"%s"' % cmd.sanitize_path(po_dst_file.u_path)                             # Output file

    # Command line execution
    #-----------------------
    du_output = cmd.execute(u_cmd)

    if du_output['u_stderr']:
        print du_output['u_stderr']

    # Transformation object result
    ti_final_size = _img_get_size(po_dst_file.u_path)
    i_extra_top = max(0, i_shadow1_blur - i_shadow1_dist, i_shadow2_blur)
    i_extra_bottom = max(0, i_shadow1_blur + i_shadow1_dist, i_shadow2_blur)

    # Delta distances in rotated image in screen coordinates
    tf_dx = (0.5 * f_cos * ti_cvr_size_final[0], -0.5 * f_sin * ti_cvr_size_final[0])
    tf_dy = (-0.5 * f_sin * ti_cvr_size_final[1], -0.5 * f_cos * ti_cvr_size_final[1])

    tf_center = (0.5 * ti_final_size[0] + i_stp_x * f_cos,
                 0.5 * (ti_final_size[1] - i_extra_top - i_extra_bottom) + i_extra_top)
    tf_left = (tf_center[0] - tf_dx[0], tf_center[1] - tf_dx[1])
    tf_right = (tf_center[0] + tf_dx[0], tf_center[1] + tf_dx[1])
    tf_top = (tf_center[0] + tf_dy[0], tf_center[1] + tf_dy[1])
    tf_top_left = (tf_top[0] - tf_dx[0], tf_top[1] - tf_dx[1])
    tf_top_right = (tf_top[0] + tf_dx[0], tf_top[1] + tf_dx[1])
    tf_bottom = (tf_center[0] - tf_dy[0], tf_center[1] - tf_dy[1])
    tf_bottom_left = (tf_bottom[0] - tf_dx[0], tf_bottom[1] - tf_dx[1])
    tf_bottom_right = (tf_bottom[0] + tf_dx[0], tf_bottom[1] + tf_dx[1])

    # Transformation object result
    o_img_transformation = ImgKeyCoords()
    o_img_transformation.ti_size = ti_final_size
    o_img_transformation.tf_top_left = (tf_top_left[0] / ti_final_size[0], tf_top_left[1] / ti_final_size[1])
    o_img_transformation.tf_top = (tf_top[0] / ti_final_size[0], tf_top[1] / ti_final_size[1])
    o_img_transformation.tf_top_right = (tf_top_right[0] / ti_final_size[0], tf_top_right[1] / ti_final_size[1])
    o_img_transformation.tf_left = (tf_left[0] / ti_final_size[0], tf_left[1] / ti_final_size[1])
    o_img_transformation.tf_center = (tf_center[0] / ti_final_size[0], tf_center[1] / ti_final_size[1])
    o_img_transformation.tf_right = (tf_right[0] / ti_final_size[0], tf_right[1] / ti_final_size[1])
    o_img_transformation.tf_bottom_left = (tf_bottom_left[0] / ti_final_size[0],
                                           tf_bottom_left[1] / ti_final_size[1])
    o_img_transformation.tf_bottom = (tf_bottom[0] / ti_final_size[0], tf_bottom[1] / ti_final_size[1])
    o_img_transformation.tf_bottom_right = (tf_bottom_right[0] / ti_final_size[0],
                                            tf_bottom_right[1] / ti_final_size[1])

    # Debug code to overlay image regions
    #_draw_coordinates(po_dst_file, o_img_transformation)

    return o_img_transformation
コード例 #3
0
ファイル: imagemagick.py プロジェクト: PixelGordo/HQ-Tools
def _cnv_frame(po_src_file, po_dst_file, po_cfg):
    """
    Image conversion that adds a picture frame around the image and soft reflections.

    Focus point is used to set the center of the reflection image.

    :param po_src_file: Input file. i.e. '/home/john/original_picture.jpg'

    :param po_dst_file: Output file. i.e. '/home/john/modified_picture.png'

    :param po_cfg: Configuration object. See hq_img_convert to see

    :return: An ImgKeyCoords object containing the relative coordinates (0.0-1.0) of 9 key positions (top-left, top,
             top-right, left, center, right, bottom-left, bottom, bottom-right.
    """

    # Media preparation
    #------------------
    o_img_light = files.FilePath(o_MEDIA_ROOT_FP.u_path, u'frame', u'brightness.png')
    o_img_light.absfile()

    # Variables preparation for imagemagick command
    #----------------------------------------------
    ti_img_size = geom.max_rect_in(ptf_rec_out=po_cfg.ti_size, ptf_asp_in=po_cfg.tf_aspect)
    i_light_size = 2 * max(ti_img_size[0], ti_img_size[1])
    f_aspect_ratio = po_cfg.tf_aspect[0] / po_cfg.tf_aspect[1]
    f_gb_aspect_ratio = 160.0 / 144.0

    # Real location (x,y) in pixels of the focus point of the image
    ti_focus = (int(po_cfg.tf_options[0] * ti_img_size[0]), int(po_cfg.tf_options[1] * ti_img_size[1]))

    # Then, the offsets are calculated to make the center of the light image fall over that point. Imagemagick format
    # for offsets in geometry is +x+y when moving the top-left corner of the overlay image x pixels to the right and y
    # pixels to the bottom.
    ti_foc_img_off = (- 0.5 * i_light_size + ti_focus[0], - 0.5 * i_light_size + ti_focus[1])
    if ti_foc_img_off[0] >= 0:
        u_foc_img_extra_x = u'+'
    else:
        u_foc_img_extra_x = u''

    if ti_foc_img_off[1] >= 0:
        u_foc_img_extra_y = u'+'
    else:
        u_foc_img_extra_y = u''

    u_foc_img_off = u'%s%i%s%i' % (u_foc_img_extra_x, ti_foc_img_off[0], u_foc_img_extra_y, ti_foc_img_off[1])

    # Frame configuration
    i_frame_thickness = math.ceil(0.03 * min(po_cfg.ti_size))
    u_frame_color = u'#f0f0f0'
    ti_frame_size = (ti_img_size[0] + 2 * i_frame_thickness, ti_img_size[1] + 2 * i_frame_thickness)

    # Shadow configuration
    i_shadow_dist = math.ceil(0.005 * min(po_cfg.ti_size))
    i_shadow_opac = 60                                                                       # 0-100
    i_shadow_blur = math.ceil(0.0025 * max(po_cfg.ti_size))

    # Sin and Cos of the rotation are going to be used several times so I pre-calculate them to make the script a bit
    # faster.
    f_sin = math.sin(math.radians(po_cfg.f_rotation))
    f_cos = math.cos(math.radians(po_cfg.f_rotation))

    # Number of image colors to colorize gameboy screenshots
    i_colors = _img_count_colors(po_src_file.u_path)
    b_grayscale = _img_is_grayscale(po_src_file.u_path)

    # Command line build
    #-------------------
    u_cmd = u'convert '
    u_cmd += u'"%s" ' % cmd.sanitize_path(po_src_file.u_path)                                # Source file

    if f_aspect_ratio == f_gb_aspect_ratio and i_colors <= 4 and b_grayscale:                # GameBoy (mono) color tint
        u_cmd += u'+level-colors "#0f380e,#9bbb0e" '
    #else:
    #    print po_src_file.u_path
    #    print 'aspect: %f (!= %f)' % (f_aspect_ratio, f_gb_aspect_ratio)
    #    print 'colors: %i' % i_colors
    #    print '   b/w: %s' % b_grayscale

    u_cmd += u'-resize %ix%i! ' % (ti_img_size[0], ti_img_size[1])                           # Resizing
    u_cmd += u'-background transparent '                                                     # Transparent background

    u_cmd += u'\( "%s" -resize %ix%i! -geometry %s \) -composite ' % (cmd.sanitize_path(o_img_light.u_path),
                                                                      i_light_size,
                                                                      i_light_size,
                                                                      u_foc_img_off)         # Light/shadow add

    u_cmd += u'-bordercolor "%s" -border %i ' % (u_frame_color, i_frame_thickness)         # Frame border
    u_cmd += u'-rotate %f ' % po_cfg.f_rotation                                              # Rotation
    u_cmd += u'\( -clone 0 -background black -shadow %ix%i+0+%i \) ' % (i_shadow_opac,
                                                                        i_shadow_blur,
                                                                        i_shadow_dist)       # Shadow creation
    u_cmd += u'-reverse -background none -layers merge +repage '                             # Shadow composition

    u_cmd += u'-background "#%s" -flatten ' % po_cfg.u_color                                 # Background color
    u_cmd += u'"%s"' % cmd.sanitize_path(po_dst_file.u_path)                                 # Output file

    # Command line execution
    #-----------------------
    du_output = cmd.execute(u_cmd)

    if du_output['u_stderr']:
        print du_output['u_stderr']

    # Coordinates calculation after image manipulation
    #-------------------------------------------------
    ti_img_size = _img_get_size(po_dst_file.u_path)

    i_extra_top = max(0, i_shadow_blur - i_shadow_dist)
    i_extra_bottom = max(0, i_shadow_blur + i_shadow_dist)

    # Delta distances in rotated image in screen coordinates
    tf_dx = (0.5 * ti_frame_size[0] * f_cos, 0.5 * ti_frame_size[0] * f_sin)
    tf_dy = (0.5 * ti_frame_size[1] * f_sin, 0.5 * ti_frame_size[1] * f_cos)

    # Absolute offsets of image key-positions
    tf_center = (0.5 * ti_img_size[0], 0.5 * (ti_img_size[1] - i_extra_top - i_extra_bottom) + i_extra_top)
    tf_left = (tf_center[0] - tf_dx[0], tf_center[1] + tf_dx[1])
    tf_right = (tf_center[0] + tf_dx[0], tf_center[1] - tf_dx[1])

    tf_bottom = (tf_center[0] + tf_dy[0], tf_center[1] + tf_dy[1])
    tf_bottom_left = (tf_bottom[0] - tf_dx[0], tf_bottom[1] + tf_dx[1])
    tf_bottom_right = (tf_bottom[0] + tf_dx[0], tf_bottom[1] - tf_dx[1])

    tf_top = (tf_center[0] - tf_dy[0], tf_center[1] - tf_dy[1])
    tf_top_left = (tf_top[0] - tf_dx[0], tf_top[1] + tf_dx[1])
    tf_top_right = (tf_top[0] + tf_dx[0], tf_top[1] - tf_dx[1])

    # Transformation object result
    o_img_transformation = ImgKeyCoords()
    o_img_transformation.ti_size = ti_img_size
    o_img_transformation.tf_top_left = (tf_top_left[0] / ti_img_size[0], tf_top_left[1] / ti_img_size[1])
    o_img_transformation.tf_top = (tf_top[0] / ti_img_size[0], tf_top[1] / ti_img_size[1])
    o_img_transformation.tf_top_right = (tf_top_right[0] / ti_img_size[0], tf_top_right[1] / ti_img_size[1])
    o_img_transformation.tf_left = (tf_left[0] / ti_img_size[0], tf_left[1] / ti_img_size[1])
    o_img_transformation.tf_center = (tf_center[0] / ti_img_size[0], tf_center[1] / ti_img_size[1])
    o_img_transformation.tf_right = (tf_right[0] / ti_img_size[0], tf_right[1] / ti_img_size[1])
    o_img_transformation.tf_bottom_left = (tf_bottom_left[0] / ti_img_size[0], tf_bottom_left[1] / ti_img_size[1])
    o_img_transformation.tf_bottom = (tf_bottom[0] / ti_img_size[0], tf_bottom[1] / ti_img_size[1])
    o_img_transformation.tf_bottom_right = (tf_bottom_right[0] / ti_img_size[0], tf_bottom_right[1] / ti_img_size[1])

    # Debug code to overlay image regions
    # draw_coordinates(po_dst_file, o_img_transformation)

    return o_img_transformation