1796 lines
62 KiB
Python
1796 lines
62 KiB
Python
'''
|
|
Copyright (C) 2021 - 2024 Akaneyu
|
|
|
|
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
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
'''
|
|
import bpy
|
|
from . import operators
|
|
from . import app
|
|
|
|
def get_icon_id(icon_name):
|
|
session = app.get_session()
|
|
|
|
if icon_name in session.icons:
|
|
return session.icons[icon_name].icon_id
|
|
else:
|
|
return 0
|
|
|
|
def menu_func(self, context):
|
|
area_session = app.get_area_session(context)
|
|
|
|
layout = self.layout
|
|
|
|
if context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER':
|
|
|
|
layout.separator()
|
|
layout.label(text='Image Editor+')
|
|
|
|
if area_session.selection:
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_make_selection.bl_idname, text='Select Box',
|
|
icon_value=get_icon_id('select'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_cancel_selection.bl_idname, text='Deselect',
|
|
icon_value=get_icon_id('deselect'))
|
|
else:
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_make_selection.bl_idname, text='Select Box',
|
|
icon_value=get_icon_id('select'))
|
|
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_edit_menu.bl_idname, text='Edit')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_layers_menu.bl_idname, text='Pasted Layers')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_transform_menu.bl_idname, text='Transform')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_transform_layer_menu.bl_idname, text='Transform Layer')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_offset_menu.bl_idname, text='Offset')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_adjust_menu.bl_idname, text='Adjust')
|
|
layout.menu(IMAGE_EDITOR_PLUS_MT_filter_menu.bl_idname, text='Filter')
|
|
|
|
def reset_scale_properties(self, context):
|
|
if self.reset:
|
|
self.width_pixels = self.original_width
|
|
self.height_pixels = self.original_height
|
|
self.property_unset('width_percent')
|
|
self.property_unset('height_percent')
|
|
self.property_unset('keep_aspect_ratio')
|
|
self.property_unset('scale_layers')
|
|
|
|
self.reset = False
|
|
|
|
def update_scale_width_properties(self, context):
|
|
if self.skip_property_update:
|
|
return
|
|
|
|
if self.keep_aspect_ratio:
|
|
self.skip_property_update = True
|
|
|
|
ratio = self.original_width / self.original_height
|
|
self.height_pixels = int(self.width_pixels / ratio)
|
|
self.height_percent = self.width_percent
|
|
|
|
self.skip_property_update = False
|
|
|
|
def update_scale_height_properties(self, context):
|
|
if self.skip_property_update:
|
|
return
|
|
|
|
if self.keep_aspect_ratio:
|
|
self.skip_property_update = True
|
|
|
|
ratio = self.original_width / self.original_height
|
|
self.width_pixels = int(self.height_pixels * ratio)
|
|
self.width_percent = self.height_percent
|
|
|
|
self.skip_property_update = False
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_scale_dialog(bpy.types.Operator):
|
|
"""Scale the image"""
|
|
bl_idname = 'image_editor_plus.scale_image_dialog'
|
|
bl_label = "Scale Image"
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_scale_properties)
|
|
unit: bpy.props.EnumProperty(options={'SKIP_SAVE'}, items=(
|
|
('pixels', 'Pixels', 'In pixels'),
|
|
('percent', 'Percent', 'In percent')))
|
|
width_pixels: bpy.props.IntProperty(name='Width',
|
|
min=1, options={'SKIP_SAVE'},
|
|
update=update_scale_width_properties)
|
|
height_pixels: bpy.props.IntProperty(name='Height',
|
|
min=1, options={'SKIP_SAVE'},
|
|
update=update_scale_height_properties)
|
|
width_percent: bpy.props.FloatProperty(name='Width', subtype='PERCENTAGE',
|
|
min=1.0, soft_max=200.0, default=100.0, options={'SKIP_SAVE'},
|
|
update=update_scale_width_properties)
|
|
height_percent: bpy.props.FloatProperty(name='Height', subtype='PERCENTAGE',
|
|
min=1.0, soft_max=200.0, default=100.0, options={'SKIP_SAVE'},
|
|
update=update_scale_height_properties)
|
|
keep_aspect_ratio: bpy.props.BoolProperty(name='Keep Aspect Ratio', default=True,
|
|
options={'SKIP_SAVE'}, update=update_scale_width_properties)
|
|
scale_layers: bpy.props.BoolProperty(name='Scale Layers', default=True,
|
|
options={'SKIP_SAVE'}, description='Only if Keep Aspect Ratio is turned on')
|
|
original_width: bpy.props.IntProperty()
|
|
original_height: bpy.props.IntProperty()
|
|
skip_property_update: bpy.props.BoolProperty()
|
|
|
|
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_pixels = width
|
|
self.height_pixels = height
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
if self.unit == 'pixels':
|
|
width = self.width_pixels
|
|
height = self.height_pixels
|
|
else: # percent
|
|
width = int(self.original_width * self.width_percent / 100.0)
|
|
height = int(self.original_height * self.height_percent / 100.0)
|
|
|
|
if width < 1:
|
|
width = 1
|
|
if height < 1:
|
|
height = 1
|
|
|
|
scale_layers = False
|
|
if self.keep_aspect_ratio:
|
|
scale_layers = self.scale_layers
|
|
|
|
bpy.ops.image_editor_plus.scale('EXEC_DEFAULT', False,
|
|
width=width, height=height, scale_layers=scale_layers)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.row()
|
|
row.prop(self, "unit", expand=True)
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Width')
|
|
|
|
if self.unit == 'pixels':
|
|
row.prop(self, 'width_pixels', text='')
|
|
else:
|
|
row.prop(self, 'width_percent', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Height')
|
|
|
|
if self.unit == 'pixels':
|
|
row.prop(self, 'height_pixels', text='')
|
|
else:
|
|
row.prop(self, 'height_percent', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'keep_aspect_ratio')
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
|
|
if self.keep_aspect_ratio:
|
|
row.prop(self, 'scale_layers')
|
|
else:
|
|
row.label(text='No layers scaled.')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
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):
|
|
if self.preview:
|
|
update_offset_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_offset_properties(self, context):
|
|
if self.reset:
|
|
self.offset_properties.property_unset('offset_x')
|
|
self.offset_properties.property_unset('offset_y')
|
|
self.property_unset('offset_edge_behavior')
|
|
update_offset_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_offset_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.offset('EXEC_DEFAULT', False,
|
|
offset_x=self.offset_properties.offset_x,
|
|
offset_y=self.offset_properties.offset_y,
|
|
offset_edge_behavior=self.offset_edge_behavior)
|
|
|
|
# wrap these properties to change their attributes dynamically
|
|
class IMAGE_EDITOR_PLUS_OffsetPropertyGroup(bpy.types.PropertyGroup):
|
|
offset_x: bpy.props.IntProperty()
|
|
offset_y: bpy.props.IntProperty()
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_offset_dialog(bpy.types.Operator):
|
|
"""Offset the image"""
|
|
bl_idname = 'image_editor_plus.offset_dialog'
|
|
bl_label = "Offset"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_offset_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_offset_properties)
|
|
offset_properties: bpy.props.PointerProperty(options={'SKIP_SAVE'},
|
|
type=IMAGE_EDITOR_PLUS_OffsetPropertyGroup)
|
|
offset_edge_behavior: bpy.props.EnumProperty(options={'SKIP_SAVE'}, items=(
|
|
('wrap', 'Wrap', 'Wrap image around'),
|
|
('edge', 'Edge', 'Repeat edge pixels')),
|
|
update=update_offset_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
width, height = img.size
|
|
|
|
selection = app.get_target_selection(context)
|
|
if selection:
|
|
width = selection[1][0] - selection[0][0]
|
|
height = selection[1][1] - selection[0][1]
|
|
|
|
IMAGE_EDITOR_PLUS_OffsetPropertyGroup.offset_x = \
|
|
bpy.props.IntProperty(name='Offset X', subtype='FACTOR',
|
|
min=-width + 1, max=width - 1,
|
|
update=(lambda _self, context: update_offset_properties(self, context)))
|
|
|
|
IMAGE_EDITOR_PLUS_OffsetPropertyGroup.offset_y = \
|
|
bpy.props.IntProperty(name='Offset Y', subtype='FACTOR',
|
|
min=-width + 1, max=width - 1,
|
|
update=(lambda _self, context: update_offset_properties(self, context)))
|
|
|
|
update_offset_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.offset('EXEC_DEFAULT', False,
|
|
offset_x=self.offset_properties.offset_x,
|
|
offset_y=self.offset_properties.offset_y,
|
|
offset_edge_behavior=self.offset_edge_behavior)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Offset X')
|
|
row.prop(self.offset_properties, 'offset_x', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Offset Y')
|
|
row.prop(self.offset_properties, 'offset_y', text='')
|
|
|
|
row = layout.row()
|
|
row.prop(self, "offset_edge_behavior", expand=True)
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_adjust_color_properties(self, context):
|
|
if self.preview:
|
|
update_adjust_color_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_adjust_color_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('adjust_hue')
|
|
self.property_unset('adjust_lightness')
|
|
self.property_unset('adjust_saturation')
|
|
update_adjust_color_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_adjust_color_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.adjust_color('EXEC_DEFAULT', False,
|
|
adjust_hue=self.adjust_hue,
|
|
adjust_lightness=self.adjust_lightness,
|
|
adjust_saturation=self.adjust_saturation)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_adjust_color_dialog(bpy.types.Operator):
|
|
"""Adjust hue/saturation/lightness of the image"""
|
|
bl_idname = 'image_editor_plus.adjust_color_dialog'
|
|
bl_label = "Hue/Saturation"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_adjust_color_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'},
|
|
update=reset_adjust_color_properties)
|
|
adjust_hue: bpy.props.FloatProperty(name='Hue', subtype='FACTOR',
|
|
min=-180, max=180, default=0, options={'SKIP_SAVE'},
|
|
update=update_adjust_color_properties)
|
|
adjust_lightness: bpy.props.FloatProperty(name='Lightness', subtype='PERCENTAGE',
|
|
min=0, max=200, default=100, options={'SKIP_SAVE'},
|
|
update=update_adjust_color_properties)
|
|
adjust_saturation: bpy.props.FloatProperty(name='Saturation', subtype='PERCENTAGE',
|
|
min=0, max=200, default=100, options={'SKIP_SAVE'},
|
|
update=update_adjust_color_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img, need_hsl=True)
|
|
|
|
update_adjust_color_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.adjust_color('EXEC_DEFAULT', False,
|
|
adjust_hue=self.adjust_hue,
|
|
adjust_lightness=self.adjust_lightness,
|
|
adjust_saturation=self.adjust_saturation)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Hue')
|
|
row.prop(self, 'adjust_hue', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Lightness')
|
|
row.prop(self, 'adjust_lightness', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Saturation')
|
|
row.prop(self, 'adjust_saturation', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_adjust_brightness_properties(self, context):
|
|
if self.preview:
|
|
update_adjust_brightness_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_adjust_brightness_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('adjust_brightness')
|
|
self.property_unset('adjust_contrast')
|
|
update_adjust_brightness_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_adjust_brightness_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.adjust_brightness('EXEC_DEFAULT', False,
|
|
adjust_brightness=self.adjust_brightness,
|
|
adjust_contrast=self.adjust_contrast)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_adjust_brightness_dialog(bpy.types.Operator):
|
|
"""Adjust brightness/contrast of the image"""
|
|
bl_idname = 'image_editor_plus.adjust_brightness_dialog'
|
|
bl_label = "Brightness/Contrast"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_adjust_brightness_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'},
|
|
update=reset_adjust_brightness_properties)
|
|
adjust_brightness: bpy.props.FloatProperty(name='Brightness', subtype='PERCENTAGE',
|
|
min=0, max=200, default=100, options={'SKIP_SAVE'},
|
|
update=update_adjust_brightness_properties)
|
|
adjust_contrast: bpy.props.FloatProperty(name='Contrast', subtype='PERCENTAGE',
|
|
min=0, max=200, default=100, options={'SKIP_SAVE'},
|
|
update=update_adjust_brightness_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_adjust_brightness_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.adjust_brightness('EXEC_DEFAULT', False,
|
|
adjust_brightness=self.adjust_brightness,
|
|
adjust_contrast=self.adjust_contrast)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Brightness')
|
|
row.prop(self, 'adjust_brightness', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Contrast')
|
|
row.prop(self, 'adjust_contrast', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_adjust_gamma_properties(self, context):
|
|
if self.preview:
|
|
update_adjust_gamma_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_adjust_gamma_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('adjust_gamma')
|
|
update_adjust_gamma_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_adjust_gamma_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.adjust_gamma('EXEC_DEFAULT', False,
|
|
adjust_gamma=self.adjust_gamma)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_adjust_gamma_dialog(bpy.types.Operator):
|
|
"""Adjust gamma of the image"""
|
|
bl_idname = 'image_editor_plus.adjust_gamma_dialog'
|
|
bl_label = "Gamma"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_adjust_gamma_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'},
|
|
update=reset_adjust_gamma_properties)
|
|
adjust_gamma: bpy.props.FloatProperty(name='Gamma', subtype='FACTOR',
|
|
min=0.01, soft_max=3.0, default=1.0, options={'SKIP_SAVE'},
|
|
update=update_adjust_gamma_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_adjust_gamma_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.adjust_gamma('EXEC_DEFAULT', False,
|
|
adjust_gamma=self.adjust_gamma)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Gamma')
|
|
row.prop(self, 'adjust_gamma', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_adjust_color_curve_properties(self, context):
|
|
if not self.preview:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_adjust_color_curve_properties(self, context):
|
|
if self.reset:
|
|
app.reset_curve_mapping()
|
|
|
|
self.reset = False
|
|
|
|
def update_adjust_color_curve_properties(self, context):
|
|
if self.update_preview:
|
|
self.update_preview = False
|
|
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.adjust_color_curve('EXEC_DEFAULT', False)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_adjust_color_curve_dialog(bpy.types.Operator):
|
|
"""Adjust color curve of the image"""
|
|
bl_idname = 'image_editor_plus.adjust_curve_dialog'
|
|
bl_label = "Adjust Color Curve"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_adjust_color_curve_properties,
|
|
description='Preview manually (Need an update operation)')
|
|
update_preview: bpy.props.BoolProperty(options={'SKIP_SAVE'},
|
|
update=update_adjust_color_curve_properties,
|
|
description='Update preview')
|
|
reset: bpy.props.BoolProperty(update=reset_adjust_color_curve_properties,
|
|
options={'SKIP_SAVE'})
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
app.reset_curve_mapping()
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.adjust_color_curve('EXEC_DEFAULT', False)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
row.prop(self, 'update_preview', text='Update', toggle=True, icon='FILE_REFRESH')
|
|
|
|
layout.separator()
|
|
|
|
curve_node = app.get_curve_node()
|
|
|
|
col = layout.column(align=True)
|
|
col.template_curve_mapping(curve_node, 'mapping', type='COLOR')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_replace_color_properties(self, context):
|
|
if self.preview:
|
|
update_replace_color_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_replace_color_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('source_color')
|
|
self.property_unset('replace_color')
|
|
self.property_unset('color_threshold')
|
|
update_replace_color_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_replace_color_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.replace_color('EXEC_DEFAULT', False,
|
|
source_color=self.source_color,
|
|
replace_color=self.replace_color,
|
|
color_threshold=self.color_threshold)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_replace_color_dialog(bpy.types.Operator):
|
|
"""Replace one color in the image with another"""
|
|
bl_idname = 'image_editor_plus.replace_color_dialog'
|
|
bl_label = "Replace Color"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_replace_color_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'},
|
|
update=reset_replace_color_properties)
|
|
source_color: bpy.props.FloatVectorProperty(name='Source Color', subtype='COLOR_GAMMA',
|
|
min=0, max=1.0, size=3, default=(1.0, 1.0, 1.0), options={'SKIP_SAVE'},
|
|
update=update_replace_color_properties) # no alpha
|
|
replace_color: bpy.props.FloatVectorProperty(name='Replace Color', subtype='COLOR_GAMMA',
|
|
min=0, max=1.0, size=4, default=(0, 0, 0, 1.0), options={'SKIP_SAVE'},
|
|
update=update_replace_color_properties)
|
|
color_threshold: bpy.props.FloatProperty(name='Threshold', subtype='FACTOR',
|
|
min=0, max=1.0, default=0.1, options={'SKIP_SAVE'},
|
|
update=update_replace_color_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_replace_color_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.replace_color('EXEC_DEFAULT', False,
|
|
source_color=self.source_color,
|
|
replace_color=self.replace_color,
|
|
color_threshold=self.color_threshold)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Source Color')
|
|
row.prop(self, 'source_color', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Replace Color')
|
|
row.prop(self, 'replace_color', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Threshold')
|
|
row.prop(self, 'color_threshold', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_blur_properties(self, context):
|
|
if self.preview:
|
|
update_blur_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_blur_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('blur_size')
|
|
self.property_unset('expand_layer')
|
|
update_blur_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_blur_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.blur('EXEC_DEFAULT', False,
|
|
blur_size=self.blur_size,
|
|
expand_layer=False)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_blur_dialog(bpy.types.Operator):
|
|
"""Blur the image"""
|
|
bl_idname = 'image_editor_plus.blur_dialog'
|
|
bl_label = "Blur (Gaussian Blur)"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_blur_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_blur_properties)
|
|
blur_size: bpy.props.FloatProperty(name='Size', subtype='FACTOR',
|
|
min=0, soft_max=10.0, default=3.0, options={'SKIP_SAVE'},
|
|
update=update_blur_properties)
|
|
expand_layer: bpy.props.BoolProperty(name='Expand Layer', default=True, options={'SKIP_SAVE'},
|
|
update=update_blur_properties)
|
|
|
|
def invoke(self, context, event):
|
|
session = app.get_session()
|
|
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
layer = app.get_active_layer(context)
|
|
if layer:
|
|
session.cached_layer_location = layer.location[:]
|
|
|
|
update_blur_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.blur('EXEC_DEFAULT', False,
|
|
blur_size=self.blur_size,
|
|
expand_layer=self.expand_layer)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Size')
|
|
row.prop(self, 'blur_size', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'expand_layer')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_sharpen_properties(self, context):
|
|
if self.preview:
|
|
update_sharpen_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_sharpen_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('sharpen_radius')
|
|
self.property_unset('sharpen_amount')
|
|
self.property_unset('sharpen_threshold')
|
|
update_sharpen_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_sharpen_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.sharpen('EXEC_DEFAULT', False,
|
|
sharpen_radius=self.sharpen_radius,
|
|
sharpen_amount=self.sharpen_amount,
|
|
sharpen_threshold=self.sharpen_threshold)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_sharpen_dialog(bpy.types.Operator):
|
|
"""Sharpen the image"""
|
|
bl_idname = 'image_editor_plus.sharpen_dialog'
|
|
bl_label = "Sharpen (Unsharp Mask)"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_sharpen_properties)
|
|
reset: bpy.props.BoolProperty(update=reset_sharpen_properties, options={'SKIP_SAVE'})
|
|
sharpen_radius: bpy.props.FloatProperty(name='Radius', subtype='FACTOR',
|
|
min=0, soft_max=10.0, default=3.0, options={'SKIP_SAVE'},
|
|
update=update_sharpen_properties)
|
|
sharpen_amount: bpy.props.FloatProperty(name='Amount', subtype='FACTOR',
|
|
min=0, soft_max=10.0, default=0.5, options={'SKIP_SAVE'},
|
|
update=update_sharpen_properties)
|
|
sharpen_threshold: bpy.props.FloatProperty(name='Threshold', subtype='FACTOR',
|
|
min=0, soft_max=1.0, default=0, options={'SKIP_SAVE'},
|
|
update=update_sharpen_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_sharpen_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.sharpen('EXEC_DEFAULT', False,
|
|
sharpen_radius=self.sharpen_radius,
|
|
sharpen_amount=self.sharpen_amount,
|
|
sharpen_threshold=self.sharpen_threshold)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Radius')
|
|
row.prop(self, 'sharpen_radius', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Amount')
|
|
row.prop(self, 'sharpen_amount', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Threshold')
|
|
row.prop(self, 'sharpen_threshold', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_add_noise_properties(self, context):
|
|
if self.preview:
|
|
update_add_noise_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_add_noise_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('add_noise_intensity')
|
|
update_add_noise_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_add_noise_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.add_noise('EXEC_DEFAULT', False,
|
|
add_noise_intensity=self.add_noise_intensity)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_add_noise_dialog(bpy.types.Operator):
|
|
"""Add some noise to the image"""
|
|
bl_idname = 'image_editor_plus.add_noise_dialog'
|
|
bl_label = "Add Noise (Gaussian Noise)"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_add_noise_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_add_noise_properties)
|
|
add_noise_intensity: bpy.props.FloatProperty(name='Intensity', subtype='FACTOR',
|
|
min=0, soft_max=10.0, default=0.1, options={'SKIP_SAVE'},
|
|
update=update_add_noise_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_add_noise_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.add_noise('EXEC_DEFAULT', False,
|
|
add_noise_intensity=self.add_noise_intensity)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Intensity')
|
|
row.prop(self, 'add_noise_intensity', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_pixelize_properties(self, context):
|
|
if self.preview:
|
|
update_pixelize_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def reset_pixelize_properties(self, context):
|
|
if self.reset:
|
|
self.property_unset('pixelize_pixel_size')
|
|
update_pixelize_properties(self, context)
|
|
|
|
self.reset = False
|
|
|
|
def update_pixelize_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.pixelize('EXEC_DEFAULT', False,
|
|
pixelize_pixel_size=self.pixelize_pixel_size)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_pixelize_dialog(bpy.types.Operator):
|
|
"""Pixelize the image"""
|
|
bl_idname = 'image_editor_plus.pixelize_dialog'
|
|
bl_label = "Pixelize"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_pixelize_properties)
|
|
reset: bpy.props.BoolProperty(options={'SKIP_SAVE'}, update=reset_pixelize_properties)
|
|
pixelize_pixel_size: bpy.props.IntProperty(name='Pixel Size', subtype='FACTOR',
|
|
min=1, soft_max=64, default=16, options={'SKIP_SAVE'},
|
|
update=update_pixelize_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_pixelize_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.pixelize('EXEC_DEFAULT', False,
|
|
pixelize_pixel_size=self.pixelize_pixel_size)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
layout.separator()
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Pixel Size')
|
|
row.prop(self, 'pixelize_pixel_size', text='')
|
|
|
|
row = layout.split(factor=0.7)
|
|
row.column()
|
|
row.prop(self, 'reset', text='Reset', toggle=True)
|
|
|
|
def preview_make_seamless_properties(self, context):
|
|
if self.preview:
|
|
update_make_seamless_properties(self, context)
|
|
else:
|
|
img = app.get_target_image(context)
|
|
if img:
|
|
app.revert_image_cache(img)
|
|
app.refresh_image(context)
|
|
|
|
def update_make_seamless_properties(self, context):
|
|
if self.preview:
|
|
bpy.ops.image_editor_plus.make_seamless('EXEC_DEFAULT', False)
|
|
|
|
class IMAGE_EDITOR_PLUS_OT_make_seamless_dialog(bpy.types.Operator):
|
|
"""Turn the image into seamless tile"""
|
|
bl_idname = 'image_editor_plus.make_seamless_dialog'
|
|
bl_label = "Make Seamless"
|
|
preview: bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'},
|
|
update=preview_make_seamless_properties)
|
|
|
|
def invoke(self, context, event):
|
|
wm = context.window_manager
|
|
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.cache_image(img)
|
|
|
|
update_make_seamless_properties(self, context)
|
|
|
|
return wm.invoke_props_dialog(self)
|
|
|
|
def execute(self, context):
|
|
bpy.ops.image_editor_plus.make_seamless('EXEC_DEFAULT', False)
|
|
|
|
return {'FINISHED'}
|
|
|
|
def cancel(self, context):
|
|
img = app.get_target_image(context)
|
|
if not img:
|
|
return {'CANCELLED'}
|
|
|
|
app.revert_image_cache(img)
|
|
app.clear_image_cache()
|
|
app.refresh_image(context)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
row = layout.split(align=True)
|
|
row.column()
|
|
row.prop(self, 'preview', text='Preview', toggle=True, icon='VIEWZOOM')
|
|
|
|
class IMAGE_EDITOR_PLUS_UL_layer_list(bpy.types.UIList):
|
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
|
icon_value = 0
|
|
img = bpy.data.images.get(item.name)
|
|
if img:
|
|
icon_value = bpy.types.UILayout.icon(img)
|
|
|
|
row = layout.row()
|
|
|
|
row.alignment = 'EXPAND'
|
|
row.prop(item, 'label', text='', emboss=False, icon_value=icon_value)
|
|
|
|
hide_icon = 'HIDE_ON' if item.hide else 'HIDE_OFF'
|
|
row.prop(item, 'hide', text='', emboss=False, icon=hide_icon)
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_edit_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_edit_menu"
|
|
bl_label = "Edit"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_fill_with_fg_color.bl_idname, text='Fill with FG Color',
|
|
icon_value=get_icon_id('fill'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_fill_with_bg_color.bl_idname, text='Fill with BG Color',
|
|
icon_value=get_icon_id('fill'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_clear.bl_idname, text='Clear',
|
|
icon_value=get_icon_id('clear'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_cut.bl_idname, text='Cut',
|
|
icon_value=get_icon_id('cut'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_copy.bl_idname, text='Copy', icon='COPYDOWN')
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_paste.bl_idname, text='Paste', icon='PASTEDOWN')
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_crop.bl_idname, text='Crop',
|
|
icon_value=get_icon_id('crop'))
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_layers_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_layers_menu"
|
|
bl_label = "Pasted Layers"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_deselect_layer.bl_idname, text='Deselect Layer',
|
|
icon_value=get_icon_id('deselect'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_move_layer.bl_idname, text='Move',
|
|
icon_value=get_icon_id('move'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer.bl_idname, text='Rotate',
|
|
icon_value=get_icon_id('rotate'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_scale_layer.bl_idname, text='Scale',
|
|
icon_value=get_icon_id('scale'))
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_delete_layer.bl_idname, text='Delete',
|
|
icon='TRASH')
|
|
|
|
layout.operator(operators.IMAGE_EDITOR_PLUS_OT_merge_layers.bl_idname, text='Merge Layers',
|
|
icon_value=get_icon_id('check'))
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_transform_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_transform_menu"
|
|
bl_label = "Transform"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_flip.bl_idname, text='Flip Horizontally',
|
|
icon_value=get_icon_id('flip_horz'))
|
|
op.is_vertically = False
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_flip.bl_idname, text='Flip Vertically',
|
|
icon_value=get_icon_id('flip_vert'))
|
|
op.is_vertically = True
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate.bl_idname, text="Rotate 90\u00b0 Left",
|
|
icon_value=get_icon_id('rot_left'))
|
|
op.is_left = True
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate.bl_idname, text="Rotate 90\u00b0 Right",
|
|
icon_value=get_icon_id('rot_right'))
|
|
op.is_left = False
|
|
|
|
op = layout.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='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):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_transform_layer_menu"
|
|
bl_label = "Transform Layer"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_flip_layer.bl_idname, text='Flip Horizontally',
|
|
icon_value=get_icon_id('flip_horz'))
|
|
op.is_vertically = False
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_flip_layer.bl_idname, text='Flip Vertically',
|
|
icon_value=get_icon_id('flip_vert'))
|
|
op.is_vertically = True
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer.bl_idname, text="Rotate 90\u00b0 Left",
|
|
icon_value=get_icon_id('rot_left'))
|
|
op.is_left = True
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer.bl_idname, text="Rotate 90\u00b0 Right",
|
|
icon_value=get_icon_id('rot_right'))
|
|
op.is_left = False
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer_arbitrary.bl_idname,
|
|
text="Rotate Arbitrary",
|
|
icon_value=get_icon_id('rotate'))
|
|
|
|
op = layout.operator(operators.IMAGE_EDITOR_PLUS_OT_scale_layer.bl_idname, text="Scale",
|
|
icon_value=get_icon_id('scale'))
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_offset_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_offset_menu"
|
|
bl_label = "Offset"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_offset_dialog.bl_idname, text='Offset...',
|
|
icon_value=get_icon_id('offset'))
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_adjust_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_adjust_menu"
|
|
bl_label = "Adjust"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_adjust_color_dialog.bl_idname, text='Hue/Saturation...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_adjust_brightness_dialog.bl_idname, text='Brightness/Contrast...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_adjust_gamma_dialog.bl_idname, text='Gamma...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_adjust_color_curve_dialog.bl_idname, text='Color Curve...',
|
|
icon_value=get_icon_id('color_curve'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_replace_color_dialog.bl_idname, text="Replace Color...",
|
|
icon='COLOR')
|
|
|
|
class IMAGE_EDITOR_PLUS_MT_filter_menu(bpy.types.Menu):
|
|
bl_idname = "IMAGE_EDITOR_PLUS_MT_filter_menu"
|
|
bl_label = "Filter"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_blur_dialog.bl_idname, text="Blur...",
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_sharpen_dialog.bl_idname, text="Sharpen...",
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_add_noise_dialog.bl_idname, text="Add Noise...",
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_pixelize_dialog.bl_idname, text="Pixelize...",
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
layout.operator(IMAGE_EDITOR_PLUS_OT_make_seamless_dialog.bl_idname, text='Make Seamless...',
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_select_panel(bpy.types.Panel):
|
|
bl_label = "Select"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
area_session = app.get_area_session(context)
|
|
|
|
wm = context.window_manager
|
|
props = wm.imageeditorplus_properties
|
|
|
|
layout = self.layout
|
|
|
|
if area_session.selecting:
|
|
row = layout.row()
|
|
row.enabled = False
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_make_selection.bl_idname, text='Selecting...')
|
|
else:
|
|
if area_session.selection:
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_make_selection.bl_idname, text='Select Box',
|
|
icon_value=get_icon_id('select'))
|
|
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_cancel_selection.bl_idname,
|
|
text='Deselect',
|
|
icon_value=get_icon_id('deselect'))
|
|
else:
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_make_selection.bl_idname, text='Select Box',
|
|
icon_value=get_icon_id('select'))
|
|
|
|
if area_session.selection:
|
|
img = context.area.spaces.active.image
|
|
width, height = img.size
|
|
|
|
selection = app.get_selection(context)
|
|
x1 = selection[0][0]
|
|
y1 = height - selection[1][1]
|
|
x2 = selection[1][0]
|
|
y2 = height - selection[0][1]
|
|
|
|
row = layout.row()
|
|
row.label(text='({}, {}) - ({}, {})'.format(x1, y1, x2, y2),
|
|
icon_value=get_icon_id('select'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_edit_panel(bpy.types.Panel):
|
|
bl_label = "Edit"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
props = wm.imageeditorplus_properties
|
|
|
|
layout = self.layout
|
|
|
|
row = layout.split(factor=0.9)
|
|
col = row.column()
|
|
row2 = col.split(align=True)
|
|
row2.prop(props, 'foreground_color', text='')
|
|
row2.prop(props, 'background_color', text='')
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_swap_colors.bl_idname, text='', icon='FILE_REFRESH',
|
|
emboss=False)
|
|
|
|
fill_clear_box = layout.box()
|
|
|
|
row = fill_clear_box.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_fill_with_fg_color.bl_idname, text='Fill',
|
|
icon_value=get_icon_id('fill'))
|
|
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_clear.bl_idname, text='Clear',
|
|
icon_value=get_icon_id('clear'))
|
|
|
|
copy_paste_box = layout.box()
|
|
|
|
row = copy_paste_box.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_cut.bl_idname, text='Cut',
|
|
icon_value=get_icon_id('cut'))
|
|
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_copy.bl_idname, text='Copy', icon='COPYDOWN')
|
|
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_paste.bl_idname, text='Paste', icon='PASTEDOWN')
|
|
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_crop.bl_idname, text='Crop',
|
|
icon_value=get_icon_id('crop'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_layers_panel(bpy.types.Panel):
|
|
bl_label = "Pasted Layers"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
img = context.area.spaces.active.image
|
|
if img:
|
|
img_props = img.imageeditorplus_properties
|
|
layers = img_props.layers
|
|
|
|
row = layout.row()
|
|
row.template_list("IMAGE_EDITOR_PLUS_UL_layer_list", "",
|
|
img_props, "layers",
|
|
img_props, "selected_layer_index", rows=2)
|
|
|
|
if layers:
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_deselect_layer.bl_idname, text='Deselect Layer',
|
|
icon_value=get_icon_id('deselect'))
|
|
|
|
row = layout.split(align=True)
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_move_layer.bl_idname, text='',
|
|
icon_value=get_icon_id('move'))
|
|
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_change_image_layer_order.bl_idname, text='',
|
|
icon="TRIA_UP")
|
|
op.up = True
|
|
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_change_image_layer_order.bl_idname, text='',
|
|
icon="TRIA_DOWN")
|
|
op.up = False
|
|
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_delete_layer.bl_idname, text='',
|
|
icon='TRASH')
|
|
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_merge_layers.bl_idname, text='Merge Layers',
|
|
icon_value=get_icon_id('check'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_transform_panel(bpy.types.Panel):
|
|
bl_label = "Transform"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
|
|
layout = self.layout
|
|
|
|
row = layout.split(factor=0.8)
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_flip.bl_idname, text='Flip',
|
|
icon_value=get_icon_id('flip_horz'))
|
|
op.is_vertically = False
|
|
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_flip.bl_idname, text='',
|
|
icon_value=get_icon_id('flip_vert'))
|
|
op.is_vertically = True
|
|
|
|
row = layout.split(factor=0.8)
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate.bl_idname, text='Rotate',
|
|
icon_value=get_icon_id('rot_left'))
|
|
op.is_left = True
|
|
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate.bl_idname, text='',
|
|
icon_value=get_icon_id('rot_right'))
|
|
op.is_left = False
|
|
|
|
row = layout.row()
|
|
op = row.operator(IMAGE_EDITOR_PLUS_OT_scale_dialog.bl_idname, text='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):
|
|
bl_label = "Transform Layer"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
|
|
layout = self.layout
|
|
|
|
img = context.area.spaces.active.image
|
|
if img:
|
|
img_props = img.imageeditorplus_properties
|
|
layers = img_props.layers
|
|
selected_layer_index = img_props.selected_layer_index
|
|
|
|
if selected_layer_index != -1 and selected_layer_index < len(layers):
|
|
layer = layers[selected_layer_index]
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Location')
|
|
row.prop(layer, 'location', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Rotation')
|
|
row.prop(layer, 'rotation', text='')
|
|
|
|
row = layout.split(align=True)
|
|
row.alignment = 'RIGHT'
|
|
row.label(text='Scale')
|
|
row.prop(layer, 'scale', text='')
|
|
|
|
row = layout.split(factor=0.8)
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_flip_layer.bl_idname, text='Flip',
|
|
icon_value=get_icon_id('flip_horz'))
|
|
op.is_vertically = False
|
|
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_flip_layer.bl_idname, text='',
|
|
icon_value=get_icon_id('flip_vert'))
|
|
op.is_vertically = True
|
|
|
|
row = layout.split(factor=0.6)
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer.bl_idname, text='Rotate',
|
|
icon_value=get_icon_id('rot_left'))
|
|
op.is_left = True
|
|
|
|
row = row.split(factor=0.5)
|
|
op = row.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer.bl_idname, text='',
|
|
icon_value=get_icon_id('rot_right'))
|
|
op.is_left = False
|
|
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_rotate_layer_arbitrary.bl_idname, text='',
|
|
icon_value=get_icon_id('rotate'))
|
|
|
|
row = layout.row()
|
|
row.operator(operators.IMAGE_EDITOR_PLUS_OT_scale_layer.bl_idname, text='Scale',
|
|
icon_value=get_icon_id('scale'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_offset_panel(bpy.types.Panel):
|
|
bl_label = "Offset"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
|
|
layout = self.layout
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_offset_dialog.bl_idname, text='Offset...',
|
|
icon_value=get_icon_id('offset'))
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_adjust_panel(bpy.types.Panel):
|
|
bl_label = "Adjust"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
|
|
layout = self.layout
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_adjust_color_dialog.bl_idname, text='Hue/Saturation...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_adjust_brightness_dialog.bl_idname, text='Brightness/Contrast...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_adjust_gamma_dialog.bl_idname, text='Gamma...',
|
|
icon_value=get_icon_id('adjust'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_adjust_color_curve_dialog.bl_idname, text='Color Curve...',
|
|
icon_value=get_icon_id('color_curve'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_replace_color_dialog.bl_idname, text='Replace Color...',
|
|
icon='COLOR')
|
|
|
|
class IMAGE_EDITOR_PLUS_PT_filter_panel(bpy.types.Panel):
|
|
bl_label = "Filter"
|
|
bl_space_type = "IMAGE_EDITOR"
|
|
bl_region_type = "UI"
|
|
bl_category = "Image Editor+"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.area.spaces.active.mode != 'UV' \
|
|
and context.area.spaces.active.image != None \
|
|
and context.area.spaces.active.image.source != 'VIEWER'
|
|
|
|
def draw(self, context):
|
|
wm = context.window_manager
|
|
|
|
layout = self.layout
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_blur_dialog.bl_idname, text='Blur...',
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_sharpen_dialog.bl_idname, text='Sharpen...',
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_add_noise_dialog.bl_idname, text='Add Noise...',
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_pixelize_dialog.bl_idname, text='Pixelize...',
|
|
icon_value=get_icon_id('filter'))
|
|
|
|
row = layout.row()
|
|
row.operator(IMAGE_EDITOR_PLUS_OT_make_seamless_dialog.bl_idname, text='Make Seamless...',
|
|
icon_value=get_icon_id('filter'))
|