Implement Canvas Size feature
This commit is contained in:
parent
9913ae8c35
commit
a580a4e137
|
@ -18,7 +18,7 @@
|
||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Image Editor Plus",
|
"name": "Image Editor Plus",
|
||||||
"author": "akaneyu",
|
"author": "akaneyu",
|
||||||
"version": (1, 8, 0),
|
"version": (1, 8, 1),
|
||||||
"blender": (3, 3, 0),
|
"blender": (3, 3, 0),
|
||||||
"location": "Image",
|
"location": "Image",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -64,6 +64,7 @@ classes = [
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_flip,
|
operators.IMAGE_EDITOR_PLUS_OT_flip,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_rotate,
|
operators.IMAGE_EDITOR_PLUS_OT_rotate,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_scale,
|
operators.IMAGE_EDITOR_PLUS_OT_scale,
|
||||||
|
operators.IMAGE_EDITOR_PLUS_OT_change_canvas_size,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_flip_layer,
|
operators.IMAGE_EDITOR_PLUS_OT_flip_layer,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_rotate_layer,
|
operators.IMAGE_EDITOR_PLUS_OT_rotate_layer,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_rotate_layer_arbitrary,
|
operators.IMAGE_EDITOR_PLUS_OT_rotate_layer_arbitrary,
|
||||||
|
@ -80,6 +81,7 @@ classes = [
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_pixelize,
|
operators.IMAGE_EDITOR_PLUS_OT_pixelize,
|
||||||
operators.IMAGE_EDITOR_PLUS_OT_make_seamless,
|
operators.IMAGE_EDITOR_PLUS_OT_make_seamless,
|
||||||
ui.IMAGE_EDITOR_PLUS_OT_scale_dialog,
|
ui.IMAGE_EDITOR_PLUS_OT_scale_dialog,
|
||||||
|
ui.IMAGE_EDITOR_PLUS_OT_change_canvas_size_dialog,
|
||||||
ui.IMAGE_EDITOR_PLUS_OffsetPropertyGroup,
|
ui.IMAGE_EDITOR_PLUS_OffsetPropertyGroup,
|
||||||
ui.IMAGE_EDITOR_PLUS_OT_offset_dialog,
|
ui.IMAGE_EDITOR_PLUS_OT_offset_dialog,
|
||||||
ui.IMAGE_EDITOR_PLUS_OT_adjust_color_dialog,
|
ui.IMAGE_EDITOR_PLUS_OT_adjust_color_dialog,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
'''
|
'''
|
||||||
Copyright (C) 2021 - 2023 Akaneyu
|
Copyright (C) 2021 - 2024 Akaneyu
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -764,6 +764,77 @@ class IMAGE_EDITOR_PLUS_OT_scale(bpy.types.Operator):
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class IMAGE_EDITOR_PLUS_OT_change_canvas_size(bpy.types.Operator):
|
||||||
|
"""Apply settings"""
|
||||||
|
bl_idname = "image_editor_plus.change_canvas_size"
|
||||||
|
bl_label = "Change Canvas Size"
|
||||||
|
width: bpy.props.IntProperty()
|
||||||
|
height: bpy.props.IntProperty()
|
||||||
|
expand_from_center: bpy.props.BoolProperty()
|
||||||
|
use_background_color: bpy.props.BoolProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
wm = context.window_manager
|
||||||
|
|
||||||
|
props = wm.imageeditorplus_properties
|
||||||
|
if self.use_background_color:
|
||||||
|
color = props.background_color[:] + (1.0,)
|
||||||
|
else:
|
||||||
|
color = (0, 0, 0, 0)
|
||||||
|
|
||||||
|
img = context.area.spaces.active.image
|
||||||
|
if not img:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
width, height = img.size
|
||||||
|
pixels = utils.read_pixels_from_image(img)
|
||||||
|
|
||||||
|
if self.width > width or self.height > height:
|
||||||
|
expand_width = self.width - width if self.width > width else 0
|
||||||
|
expand_height = self.height - height if self.height > height else 0
|
||||||
|
|
||||||
|
if self.expand_from_center:
|
||||||
|
expand_left = int(expand_width / 2)
|
||||||
|
expand_top = int(expand_height / 2)
|
||||||
|
expand_right = expand_width - expand_left
|
||||||
|
expand_bottom = expand_height - expand_top
|
||||||
|
else:
|
||||||
|
expand_left, expand_top = 0, 0
|
||||||
|
expand_right = expand_width
|
||||||
|
expand_bottom = expand_height
|
||||||
|
|
||||||
|
new_pixels = np.pad(pixels, ((expand_bottom, expand_top),
|
||||||
|
(expand_left, expand_right), (0, 0)),
|
||||||
|
constant_values=np.array(((color, color), (color, color), (0, 0)),
|
||||||
|
dtype=object))
|
||||||
|
else:
|
||||||
|
new_pixels = pixels
|
||||||
|
|
||||||
|
if self.width < width or self.height < height:
|
||||||
|
shrink_width = width - self.width if self.width < width else 0
|
||||||
|
shrink_height = height - self.height if self.height < height else 0
|
||||||
|
|
||||||
|
if self.expand_from_center:
|
||||||
|
shrink_left = int(shrink_width / 2)
|
||||||
|
shrink_top = int(shrink_height / 2)
|
||||||
|
else:
|
||||||
|
shrink_left, shrink_top = 0, 0
|
||||||
|
|
||||||
|
if self.height < height:
|
||||||
|
new_pixels = new_pixels[height - self.height - shrink_top:height - shrink_top,
|
||||||
|
shrink_left:self.width + shrink_left]
|
||||||
|
else:
|
||||||
|
new_pixels = new_pixels[0:self.height,
|
||||||
|
shrink_left:self.width + shrink_left]
|
||||||
|
|
||||||
|
img.scale(self.width, self.height)
|
||||||
|
|
||||||
|
utils.write_pixels_to_image(img, new_pixels)
|
||||||
|
|
||||||
|
app.refresh_image(context)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
class IMAGE_EDITOR_PLUS_OT_flip_layer(bpy.types.Operator):
|
class IMAGE_EDITOR_PLUS_OT_flip_layer(bpy.types.Operator):
|
||||||
"""Flip the layer"""
|
"""Flip the layer"""
|
||||||
bl_idname = "image_editor_plus.flip_layer"
|
bl_idname = "image_editor_plus.flip_layer"
|
||||||
|
|
94
addon/ui.py
94
addon/ui.py
|
@ -1,5 +1,5 @@
|
||||||
'''
|
'''
|
||||||
Copyright (C) 2021 - 2023 Akaneyu
|
Copyright (C) 2021 - 2024 Akaneyu
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -199,6 +199,90 @@ class IMAGE_EDITOR_PLUS_OT_scale_dialog(bpy.types.Operator):
|
||||||
row.column()
|
row.column()
|
||||||
row.prop(self, 'reset', text='Reset', toggle=True)
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
||||||
|
|
||||||
|
def reset_canvas_size_properties(self, context):
|
||||||
|
if self.reset:
|
||||||
|
self.width = self.original_width
|
||||||
|
self.height = self.original_height
|
||||||
|
self.expand_from_center = False
|
||||||
|
self.use_background_color = False
|
||||||
|
|
||||||
|
self.reset = False
|
||||||
|
|
||||||
|
class IMAGE_EDITOR_PLUS_OT_change_canvas_size_dialog(bpy.types.Operator):
|
||||||
|
"""Change the canvas size"""
|
||||||
|
bl_idname = 'image_editor_plus.change_canvas_size_dialog'
|
||||||
|
bl_label = "Canvas Size"
|
||||||
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_canvas_size_properties)
|
||||||
|
width: bpy.props.IntProperty(name='Width',
|
||||||
|
min=1, options={'SKIP_SAVE'})
|
||||||
|
height: bpy.props.IntProperty(name='Height',
|
||||||
|
min=1, options={'SKIP_SAVE'})
|
||||||
|
expand_from_center: bpy.props.BoolProperty(name='Expand from Center', default=False)
|
||||||
|
use_background_color: bpy.props.BoolProperty(name='Use Background Color', default=False)
|
||||||
|
original_width: bpy.props.IntProperty()
|
||||||
|
original_height: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
wm = context.window_manager
|
||||||
|
|
||||||
|
img = context.area.spaces.active.image
|
||||||
|
if not img:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
width, height = img.size
|
||||||
|
|
||||||
|
self.original_width = width
|
||||||
|
self.original_height = height
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
return wm.invoke_props_dialog(self)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
width = self.width
|
||||||
|
height = self.height
|
||||||
|
|
||||||
|
if width < 1:
|
||||||
|
width = 1
|
||||||
|
if height < 1:
|
||||||
|
height = 1
|
||||||
|
|
||||||
|
bpy.ops.image_editor_plus.change_canvas_size('EXEC_DEFAULT', False,
|
||||||
|
width=width, height=height, expand_from_center=self.expand_from_center,
|
||||||
|
use_background_color=self.use_background_color)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
|
||||||
|
row = layout.split(align=True)
|
||||||
|
row.alignment = 'RIGHT'
|
||||||
|
row.label(text='Width')
|
||||||
|
row.prop(self, 'width', text='')
|
||||||
|
|
||||||
|
row = layout.split(align=True)
|
||||||
|
row.alignment = 'RIGHT'
|
||||||
|
row.label(text='Height')
|
||||||
|
row.prop(self, 'height', text='')
|
||||||
|
|
||||||
|
row = layout.split(align=True)
|
||||||
|
row.column()
|
||||||
|
row.prop(self, 'expand_from_center')
|
||||||
|
|
||||||
|
row = layout.split(align=True)
|
||||||
|
row.column()
|
||||||
|
row.prop(self, 'use_background_color')
|
||||||
|
|
||||||
|
row = layout.split(align=True)
|
||||||
|
row.column()
|
||||||
|
|
||||||
|
row = layout.split(factor=0.7)
|
||||||
|
row.column()
|
||||||
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
||||||
|
|
||||||
def preview_offset_properties(self, context):
|
def preview_offset_properties(self, context):
|
||||||
if self.preview:
|
if self.preview:
|
||||||
update_offset_properties(self, context)
|
update_offset_properties(self, context)
|
||||||
|
@ -1261,6 +1345,9 @@ class IMAGE_EDITOR_PLUS_MT_transform_menu(bpy.types.Menu):
|
||||||
op = layout.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='Scale...',
|
op = layout.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='Scale...',
|
||||||
icon_value=get_icon_id('scale'))
|
icon_value=get_icon_id('scale'))
|
||||||
|
|
||||||
|
op = layout.operator(IMAGE_EDITOR_PLUS_OT_change_canvas_size_dialog.bl_idname, text='Canvas Size...',
|
||||||
|
icon_value=get_icon_id('scale'))
|
||||||
|
|
||||||
class IMAGE_EDITOR_PLUS_MT_transform_layer_menu(bpy.types.Menu):
|
class IMAGE_EDITOR_PLUS_MT_transform_layer_menu(bpy.types.Menu):
|
||||||
bl_idname = "IMAGE_EDITOR_PLUS_MT_transform_layer_menu"
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_transform_layer_menu"
|
||||||
bl_label = "Transform Layer"
|
bl_label = "Transform Layer"
|
||||||
|
@ -1536,6 +1623,11 @@ class IMAGE_EDITOR_PLUS_PT_transform_panel(bpy.types.Panel):
|
||||||
op = row.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='Scale...',
|
op = row.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='Scale...',
|
||||||
icon_value=get_icon_id('scale'))
|
icon_value=get_icon_id('scale'))
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
op = row.operator(IMAGE_EDITOR_PLUS_OT_change_canvas_size_dialog.bl_idname,
|
||||||
|
text='Canvas Size...',
|
||||||
|
icon_value=get_icon_id('scale'))
|
||||||
|
|
||||||
class IMAGE_EDITOR_PLUS_PT_transform_layer_panel(bpy.types.Panel):
|
class IMAGE_EDITOR_PLUS_PT_transform_layer_panel(bpy.types.Panel):
|
||||||
bl_label = "Transform Layer"
|
bl_label = "Transform Layer"
|
||||||
bl_space_type = "IMAGE_EDITOR"
|
bl_space_type = "IMAGE_EDITOR"
|
||||||
|
|
Loading…
Reference in New Issue