Commit 2cf75cd4 authored by dovahkiin's avatar dovahkiin

添加指定区域切割功能

parent e0eaaf86
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QSpinBox
from PyQt5.QtGui import QValidator
from PyQt5.QtCore import Qt
class EvenSpinBox(QSpinBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setMaximum(65534)
self.setMinimum(2)
self.setSingleStep(2) # 设置步长为2
def validate(self, text, pos):
try:
if len(self.suffix()):
value = int(text[len(self.prefix()):-len(self.suffix())])
else:
value = int(text[len(self.prefix()):])
if value % 2 == 0:
return QValidator.Acceptable, text, pos
else:
return QValidator.Intermediate, text, pos
except ValueError:
return QValidator.Invalid, text, pos
def fixup(self, text):
try:
if len(self.suffix()):
value = int(text[len(self.prefix()):-len(self.suffix())])
else:
value = int(text[len(self.prefix()):])
# 如果值是奇数,增加1使其成为偶数
if value % 2 != 0:
self.setValue(value + 1)
except ValueError:
pass
class _Demo(QWidget):
def __init__(self):
super().__init__()
self.spinBox = EvenSpinBox()
layout = QVBoxLayout()
layout.addWidget(self.spinBox)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication([])
demo = _Demo()
demo.show()
app.exec_()
......@@ -3,14 +3,31 @@ from typing import Dict, List, Tuple
from psd_tools.api.layers import PixelLayer, TypeLayer
class rect:
def __init__(self) -> None:
self.x = 0
self.y = 0
self.w = 1
self.h = 1
def set_value(self, x_, y_, w_, h_)->None:
self.x = x_
self.y = y_
self.w = w_
self.h = h_
def __str__(self) -> str:
return "rect(({self.x},{self.y}),({self.w},{self.h}))"
# 标志位类
class flag_data:
psd_name = ''
english = False
cobit = False
show = False
equal_size = True
Auto_cut_1 = False
psd_name = '' # psd名字
english = False # 是否需要英文
cobit = False # 是否需要共位
show = False # 是否显示
equal_size = True # 是否等大
Auto_cut_1 = False # 智能切图
self_set_cut = False # 自定义切图
range_group:List[rect] = [] # 自定义切图数组
def __str__(self) -> str:
return "psd名:{}, english:{}, cobit:{}, show:{}, equal_size:{}".format(self.psd_name, self.english, self.cobit, self.show, self.equal_size)
......
This diff is collapsed.
......@@ -6,17 +6,17 @@ import urllib.request
from random import uniform
from time import sleep
import numpy as np
import openpyxl
import psd_tools
from PIL import ImageChops,Image
from psd_tools import PSDImage
from PyQt5.QtWidgets import QMessageBox, QListWidgetItem
from PyQt5.QtGui import QColor, QBrush
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QListWidgetItem, QMessageBox
from skimage.metrics import structural_similarity as ssim
from comm_class import flag_data, lay_item
auto_cut_info = {}
class exc(object):
......@@ -304,6 +304,69 @@ def extractLayerImge(lay_info:lay_item, psd_name:str, lwdtI:QListWidgetItem):
return x1, y1, layer_name, temp_layer_name, lay_info.layer.name
def find_common_area(rect1, rect2):
x1, y1, w1, h1 = rect1
x2, y2, w2, h2 = rect2
# 计算矩形的右上角坐标
r1 = x1 + w1
t1 = y1 + h1
r2 = x2 + w2
t2 = y2 + h2
# 判断矩形是否重叠
if x1 < r2 and r1 > x2 and y1 < t2 and t1 > y2:
# 计算公共矩形的坐标和大小
x = max(x1, x2)
y = max(y1, y2)
w = min(r1, r2) - x
h = min(t1, t2) - y
return (x, y, w, h)
else:
# 没有重叠的公共面积
return None
# for x_ in range(x, w+1):
# for y_ in range(y, h+1):
# # pixel = psd_layer.as_PIL().getpixel((x_, y_))
# pixel = psd_layer.getpixel((x_, y_))
# if pixel[3] != 0:
# return True
# return False
def have_pixel(psd_layer, x, y, w, h, l_x, l_y, l_w, l_h):
# 指定你关心的范围 (left, top, right, bottom)
bounds = find_common_area((x, y, w, h), (l_x, l_y, l_w, l_h)) # 返回xywh坐标格式
if bounds == None:
return False
# xywh转成ltrb坐标格式
bounds = (bounds[0]- l_x, bounds[1]-l_y, bounds[0] + bounds[2]- l_x, bounds[1] + bounds[3]-l_y)
# 从图层中提取像素数据并转换为RGBA模式
image = psd_layer.topil().convert("RGBA")
# image.show()
cropped_image = image.crop(bounds)
a_ = 0
# cropped_image.show()
# 遍历所有像素
for x_ in range(bounds[2] - bounds[0]):
for y_ in range(bounds[3] - bounds[1]):
r, g, b, a = cropped_image.getpixel((x_, y_))
# 检查每个像素的alpha值,如果alpha值大于0, 则至少有一个不透明像素
if a > 0:
# return True
a_ += a
return a_
# # 创建一个与裁剪区域相同大小的完全透明的图片
# empty_image = Image.new('RGBA', (w, h), (0, 0, 0, 0))
# # 使用ImageChops的difference方法比较两张图片
# diff = ImageChops.difference(cropped_image, empty_image)
# # 获取像素值的和,如果和为0,说明两张图片完全相同,裁剪区域完全透明
# pixel_sum = sum(diff.getdata(), (0, 0, 0, 0))
# # 如果四个通道的像素和都为0,说明该区域完全透明,否则有像素点
# return any(value != 0 for value in pixel_sum)
def get_lay_info(psd_info:flag_data):
psd = PSDImage.open(psd_info.psd_name)
max_w = max_h = 0
......@@ -360,6 +423,7 @@ def get_lay_info(psd_info:flag_data):
layer_info_list:list[lay_item] = []
for layer in layer_list:
is_join_flag = True
layer_info_item = lay_item()
if psd_info.Auto_cut_1:
max_w = max_h = 0
......@@ -376,6 +440,22 @@ def get_lay_info(psd_info:flag_data):
break
if break_flag :
break
elif psd_info.self_set_cut:
max_w = max_h = 0
max_x = max_y= -1
print(psd_info.range_group)
is_join_flag = False
for rect_item in psd_info.range_group:
if have_pixel(layer, rect_item.x, rect_item.y, rect_item.w, rect_item.h,
layer.left, layer.top, layer.width, layer.height): # 判断图像中是否存在像素点
layer_info_item.x = rect_item.x
layer_info_item.y = rect_item.y
layer_info_item.w = rect_item.w
layer_info_item.h = rect_item.h
is_join_flag = True
break
# 坐标内没有
else:
if psd_info.cobit:
layer_info_item.x = max_x
......@@ -393,10 +473,25 @@ def get_lay_info(psd_info:flag_data):
layer_info_item.x = layer.left
layer_info_item.y = layer.top
layer_info_item.layer_name = layer.name
layer_info_item.layer = layer
print(layer_info_item)
layer_info_list.append(layer_info_item)
if is_join_flag:
layer_info_item.layer_name = layer.name
layer_info_item.layer = layer
print(layer_info_item)
layer_info_list.append(layer_info_item)
return layer_info_list
if __name__ == '__main__':
psd_data :flag_data = flag_data()
psd_data.psd_name = "NB35_W_0.psd"
psd_data.equal_size = False
from comm_class import rect
psd_data.range_group = [rect()]
psd_data.range_group[0].y = 10
psd_data.range_group[0].w = 12
psd_data.range_group[0].h = 10
psd_data.self_set_cut = 1
get_lay_info(psd_data)
......@@ -17,9 +17,11 @@ from PyQt5.QtWidgets import (QApplication, QListWidgetItem, QMessageBox,
QStatusBar, QStyleFactory, QFileDialog,
QApplication)
from comm_class import flag_data, lay_item
from comm_class import flag_data, lay_item, rect
from cut_pic import extractLayerImge, get_lay_info
from outputUI import Ui_MainWindow as Ui_Form
import EvenSpinBox
EvenSpinBox = EvenSpinBox.EvenSpinBox
fozu = r"""
##################################################################
......@@ -69,6 +71,7 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
# self.MainWindow.setWindowIcon(icon)
# self.statusbar.showMessage("初始化中")
self.lay_lwdtI = {}
self.cut_range_group_list:list[rect] = [rect()]
self.cut_pic_t = Thread(target=self.cut_pic_thread)
# ui初始化状态
self.__init()
......@@ -78,6 +81,16 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
def __init(self):
self.stackedWidget.setCurrentIndex(0)
self.let_psd_name.clear()
# 设置选择框界面的界面值
self.stk_set_cut_type.setCurrentIndex(0)
# # 设置输入框w,h仅能输入偶数
# esb_w = EvenSpinBox(self)
# # 获取布局
# layout = self.win_range_cut_w.layout()
# self.sbx_w.deleteLater()
# layout.replaceWidget(self.sbx_w,esb_w)
# self.sbx_w = esb_w
def __add_item(self, layer_data:lay_item):
temp_item = QListWidgetItem()
......@@ -85,6 +98,44 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
temp_item.setText(str(layer_data))
self.lwg_confirmed.addItem(temp_item)
def __set_range_cut_xywh(self, x, y, w, h):
self.sbx_x.setValue( x )
self.sbx_x.setValue( y )
self.sbx_w.setValue( w )
self.sbx_h.setValue( h )
# 点击按钮后添加一个选择框的范围
def __add_range_cut_item(self):
self.cbb_range_group.addItem("范围%d"%((self.cbb_range_group.count() + 1)))
self.cut_range_group_list.append(rect())
def __del_range_cut_item(self):
if (self.cbb_range_group.count() > 1):
del self.cut_range_group_list[self.cbb_range_group.currentIndex()]
self.cbb_range_group.removeItem( self.cbb_range_group.count()-1 )
self.__switchOut_range_cut_item(self.cbb_range_group.currentIndex())
def __switchOut_range_cut_item(self, index):
self.sbx_x.setValue( self.cut_range_group_list[self.cbb_range_group.currentIndex()].x )
self.sbx_y.setValue( self.cut_range_group_list[self.cbb_range_group.currentIndex()].y )
self.sbx_w.setValue( self.cut_range_group_list[self.cbb_range_group.currentIndex()].w )
self.sbx_h.setValue( self.cut_range_group_list[self.cbb_range_group.currentIndex()].h )
def __set_range_group_x(self, value):
self.cut_range_group_list[self.cbb_range_group.currentIndex()].x = value
def __set_range_group_y(self, value):
self.cut_range_group_list[self.cbb_range_group.currentIndex()].y = value
def __set_range_group_w(self, value):
self.cut_range_group_list[self.cbb_range_group.currentIndex()].w = value
def __set_range_group_h(self, value):
self.cut_range_group_list[self.cbb_range_group.currentIndex()].h = value
# 读取文件地址
def __read_file_path(self):
file_path,_ = QFileDialog.getOpenFileNames(self, "选择PSD文件", os.getcwd(), 'PSD文件(*.psd)')
......@@ -109,10 +160,13 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
psd_data.show = self.cbx_show.isChecked()
psd_data.equal_size = self.cbx_equal_size.isChecked()
psd_data.Auto_cut_1 = self.cbx_auto_1.isChecked()
psd_data.self_set_cut = self.stk_set_cut_type.currentIndex == 1
self.lib_info_data.clear()
info_prompt = "<" + psd_name + "|"
if psd_data.Auto_cut_1:
if psd_data.self_set_cut:
info_prompt = "< | 自 定 义 切 割 | >"
elif psd_data.Auto_cut_1:
info_prompt = "< | 智 能 切 割 | >"
else:
if psd_data.equal_size:
......@@ -133,7 +187,8 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
info_prompt += "无需显示>"
self.lib_info_data.setText(info_prompt)
psd_data.range_group = self.cut_range_group_list
psd_data.self_set_cut = self.stk_set_cut_type.currentIndex()
self.lay_info_s[psd_name] = get_lay_info(psd_data)
self.lwg_confirmed.addItem(str(psd_name))
# a = b = None
......@@ -190,12 +245,29 @@ class Pyqt5_Cut_psd(QtWidgets.QMainWindow, Ui_Form):
extractLayerImge(lay_info, psd_name, self.lay_lwdtI[lay_info])
self.cut_info_ok.emit()
def to_selfset_page(self):
self.stk_set_cut_type.setCurrentIndex(1)
def return_selfset_page(self):
self.stk_set_cut_type.setCurrentIndex(0)
def connects(self):
self.btn_analysis.clicked.connect(self.__analysis_psd)
self.btnb_confirmed.clicked.connect(self.__btnb_confirmed)
self.cut_info_ok.connect(self.cut_pic_ok)
self.cut_info_error.connect(self.cut_pic_error)
self.btn_select_file.clicked.connect(self.__read_file_path)
self.btn_selfset.clicked.connect(self.to_selfset_page)
self.btn_selfset_return.clicked.connect(self.return_selfset_page)
self.sbx_x.valueChanged.connect(self.__set_range_group_x)
self.sbx_y.valueChanged.connect(self.__set_range_group_y)
self.sbx_w.valueChanged.connect(self.__set_range_group_w)
self.sbx_h.valueChanged.connect(self.__set_range_group_h)
self.btn_new_range_group.clicked.connect(self.__add_range_cut_item)
self.btn_del_range_group.clicked.connect(self.__del_range_cut_item)
self.cbb_range_group.activated[int].connect(self.__switchOut_range_cut_item)
if __name__ == '__main__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment