- 创建problem目录存储问题分析和解决方案 - 添加Aspose.CAD Python问题详细报告 - 提供Java版本测试方案和完整代码 - 创建Java版本安装运行指南 - 更新README文档包含Java版本推荐 - 添加颜色元素提取相关脚本 - 提供完整的Maven项目配置
464 lines
18 KiB
Python
464 lines
18 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
提取特定颜色元素的简化脚本
|
||
功能:从DWG文件中提取颜色为(0, 255, 255)的所有元素
|
||
作者:AI Assistant
|
||
日期:2024
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import csv
|
||
import json
|
||
from pathlib import Path
|
||
import math
|
||
|
||
def print_separator(title=""):
|
||
"""打印分隔线"""
|
||
print("=" * 60)
|
||
if title:
|
||
print(f" {title} ")
|
||
print("=" * 60)
|
||
|
||
def extract_color_elements_simple(dwg_path, target_color=(0, 255, 255)):
|
||
"""提取特定颜色的元素(简化版)"""
|
||
print_separator("提取特定颜色元素")
|
||
|
||
if not os.path.exists(dwg_path):
|
||
print(f"文件不存在: {dwg_path}")
|
||
return None
|
||
|
||
try:
|
||
import aspose.cad as cad
|
||
from aspose.cad import Color
|
||
|
||
# 获取文件基本信息
|
||
file_size = os.path.getsize(dwg_path)
|
||
print(f"文件路径: {dwg_path}")
|
||
print(f"文件大小: {file_size:,} 字节 ({file_size/1024/1024:.2f} MB)")
|
||
print(f"目标颜色: RGB({target_color[0]}, {target_color[1]}, {target_color[2]})")
|
||
|
||
# 创建目标颜色对象
|
||
target_color_obj = Color.from_argb(255, target_color[0], target_color[1], target_color[2])
|
||
print(f"目标颜色对象: {target_color_obj}")
|
||
|
||
# 加载DWG文件
|
||
print("正在加载DWG文件...")
|
||
with cad.Image.load(dwg_path) as image:
|
||
print(f"成功加载DWG文件")
|
||
print(f"图像类型: {type(image).__name__}")
|
||
print(f"图像尺寸: {image.width} x {image.height}")
|
||
|
||
elements_data = []
|
||
total_elements = 0
|
||
|
||
# 方法1:尝试使用CadImage.load
|
||
print("\n方法1:使用CadImage.load")
|
||
try:
|
||
from aspose.cad.fileformats.cad import CadImage
|
||
cad_image = CadImage.load(dwg_path)
|
||
print(f"成功使用CadImage.load,类型: {type(cad_image).__name__}")
|
||
|
||
# 检查所有属性
|
||
attrs = [attr for attr in dir(cad_image) if not attr.startswith('_')]
|
||
print(f"可用属性数量: {len(attrs)}")
|
||
|
||
# 查找可能包含实体的属性
|
||
entity_attrs = [attr for attr in attrs if 'entit' in attr.lower() or 'object' in attr.lower() or 'item' in attr.lower()]
|
||
print(f"可能的实体属性: {entity_attrs}")
|
||
|
||
# 尝试访问这些属性
|
||
for attr in entity_attrs:
|
||
try:
|
||
value = getattr(cad_image, attr)
|
||
print(f" {attr}: {type(value).__name__}")
|
||
if hasattr(value, '__len__'):
|
||
print(f" 长度: {len(value)}")
|
||
|
||
# 如果长度大于0,尝试访问前几个元素
|
||
if len(value) > 0:
|
||
for i in range(min(5, len(value))):
|
||
item = value[i]
|
||
print(f" [{i}]: {type(item).__name__}")
|
||
|
||
# 检查颜色
|
||
element_info = check_element_color_simple(item, total_elements, target_color)
|
||
if element_info:
|
||
elements_data.append(element_info)
|
||
total_elements += 1
|
||
|
||
except Exception as e:
|
||
print(f" {attr}: 访问失败 - {e}")
|
||
|
||
except Exception as e:
|
||
print(f"使用CadImage.load失败: {e}")
|
||
|
||
# 方法2:尝试遍历所有可能的属性
|
||
print("\n方法2:遍历所有可能的属性")
|
||
try:
|
||
all_attrs = [attr for attr in dir(cad_image) if not attr.startswith('_')]
|
||
print(f"cad_image共有 {len(all_attrs)} 个属性")
|
||
|
||
# 查找可能包含实体的属性
|
||
entity_attrs = [attr for attr in all_attrs if 'entit' in attr.lower() or 'object' in attr.lower() or 'item' in attr.lower()]
|
||
print(f"可能的实体属性: {entity_attrs}")
|
||
|
||
for attr_name in entity_attrs:
|
||
try:
|
||
attr_value = getattr(cad_image, attr_name)
|
||
if attr_value and hasattr(attr_value, '__len__') and len(attr_value) > 0:
|
||
print(f" 找到属性 {attr_name}: {type(attr_value).__name__} (长度: {len(attr_value)})")
|
||
|
||
# 尝试遍历这个属性
|
||
for i, item in enumerate(attr_value):
|
||
item_type = type(item).__name__
|
||
print(f" {attr_name}[{i}]: {item_type}")
|
||
|
||
# 检查颜色
|
||
element_info = check_element_color_simple(item, total_elements, target_color)
|
||
if element_info:
|
||
elements_data.append(element_info)
|
||
total_elements += 1
|
||
|
||
if i >= 9: # 只显示前10个
|
||
break
|
||
except Exception as e:
|
||
print(f" 访问属性 {attr_name} 失败: {e}")
|
||
|
||
except Exception as e:
|
||
print(f"遍历属性失败: {e}")
|
||
|
||
# 方法3:尝试使用不同的API
|
||
print("\n方法3:尝试使用不同的API")
|
||
try:
|
||
# 尝试使用Image对象的其他方法
|
||
image_methods = [attr for attr in dir(image) if not attr.startswith('_') and callable(getattr(image, attr))]
|
||
print(f"Image对象方法: {image_methods}")
|
||
|
||
# 尝试使用get_strings方法
|
||
if 'get_strings' in image_methods:
|
||
try:
|
||
strings = image.get_strings()
|
||
print(f"get_strings(): {type(strings).__name__}")
|
||
if hasattr(strings, '__len__'):
|
||
print(f" 字符串数量: {len(strings)}")
|
||
for i, s in enumerate(strings[:5]):
|
||
print(f" [{i}]: {s}")
|
||
except Exception as e:
|
||
print(f"get_strings()失败: {e}")
|
||
|
||
except Exception as e:
|
||
print(f"尝试不同API失败: {e}")
|
||
|
||
print(f"\n成功提取 {total_elements} 个目标颜色元素")
|
||
return elements_data
|
||
|
||
except Exception as e:
|
||
print(f"提取元素失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return None
|
||
|
||
def check_element_color_simple(element, element_index, target_color):
|
||
"""检查元素颜色是否匹配目标颜色(简化版)"""
|
||
try:
|
||
element_type = type(element).__name__
|
||
|
||
# 尝试获取颜色信息
|
||
color_info = None
|
||
color_attrs = ['color', 'color_value', 'color_name', 'color_id']
|
||
|
||
for attr in color_attrs:
|
||
if hasattr(element, attr):
|
||
try:
|
||
color_value = getattr(element, attr)
|
||
print(f" 找到颜色属性 {attr}: {color_value} (类型: {type(color_value).__name__})")
|
||
|
||
# 检查颜色是否匹配
|
||
if is_color_match_simple(color_value, target_color):
|
||
print(f" ✓ 颜色匹配!")
|
||
color_info = str(color_value)
|
||
break
|
||
except Exception as e:
|
||
print(f" 访问颜色属性 {attr} 失败: {e}")
|
||
|
||
if color_info:
|
||
# 提取元素信息
|
||
element_info = {
|
||
'element_index': element_index,
|
||
'element_type': element_type,
|
||
'color': color_info,
|
||
'layer_name': 'Unknown',
|
||
'visible': True,
|
||
}
|
||
|
||
# 尝试获取其他属性
|
||
try:
|
||
if hasattr(element, 'layer_name'):
|
||
element_info['layer_name'] = str(getattr(element, 'layer_name', 'Unknown'))
|
||
|
||
if hasattr(element, 'visible'):
|
||
element_info['visible'] = bool(getattr(element, 'visible', True))
|
||
|
||
if hasattr(element, 'thickness'):
|
||
element_info['thickness'] = float(getattr(element, 'thickness', 0))
|
||
|
||
if hasattr(element, 'line_type_name'):
|
||
element_info['line_type'] = str(getattr(element, 'line_type_name', 'Unknown'))
|
||
|
||
# 尝试获取坐标信息
|
||
if hasattr(element, 'first_point') and hasattr(element, 'second_point'):
|
||
first_point = element.first_point
|
||
second_point = element.second_point
|
||
element_info['start_x'] = float(getattr(first_point, 'x', 0))
|
||
element_info['start_y'] = float(getattr(first_point, 'y', 0))
|
||
element_info['start_z'] = float(getattr(first_point, 'z', 0))
|
||
element_info['end_x'] = float(getattr(second_point, 'x', 0))
|
||
element_info['end_y'] = float(getattr(second_point, 'y', 0))
|
||
element_info['end_z'] = float(getattr(second_point, 'z', 0))
|
||
|
||
# 计算长度
|
||
dx = element_info['end_x'] - element_info['start_x']
|
||
dy = element_info['end_y'] - element_info['start_y']
|
||
dz = element_info['end_z'] - element_info['start_z']
|
||
length = math.sqrt(dx*dx + dy*dy + dz*dz)
|
||
element_info['length'] = round(length, 4)
|
||
|
||
elif hasattr(element, 'center') and hasattr(element, 'radius'):
|
||
center = element.center
|
||
element_info['center_x'] = float(getattr(center, 'x', 0))
|
||
element_info['center_y'] = float(getattr(center, 'y', 0))
|
||
element_info['center_z'] = float(getattr(center, 'z', 0))
|
||
element_info['radius'] = float(getattr(element, 'radius', 0))
|
||
|
||
except Exception as e:
|
||
print(f" 获取其他属性失败: {e}")
|
||
|
||
return element_info
|
||
|
||
return None
|
||
|
||
except Exception as e:
|
||
print(f"检查元素颜色失败: {e}")
|
||
return None
|
||
|
||
def is_color_match_simple(color_value, target_color):
|
||
"""检查颜色是否匹配(简化版)"""
|
||
try:
|
||
# 如果是Color对象
|
||
if hasattr(color_value, 'r') and hasattr(color_value, 'g') and hasattr(color_value, 'b'):
|
||
r = getattr(color_value, 'r', 0)
|
||
g = getattr(color_value, 'g', 0)
|
||
b = getattr(color_value, 'b', 0)
|
||
return (r, g, b) == target_color
|
||
|
||
# 如果是字符串
|
||
if isinstance(color_value, str):
|
||
color_str = str(color_value).lower()
|
||
if 'cyan' in color_str or 'aqua' in color_str:
|
||
return True
|
||
# 尝试解析RGB值
|
||
if 'rgb' in color_str or ',' in color_str:
|
||
# 简单的RGB解析
|
||
if '255' in color_str and '0' in color_str:
|
||
return True
|
||
|
||
# 如果是数字
|
||
if isinstance(color_value, (int, float)):
|
||
# AutoCAD颜色索引
|
||
if color_value == 4: # 青色
|
||
return True
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"颜色匹配检查失败: {e}")
|
||
return False
|
||
|
||
def save_elements_to_csv(elements_data, output_path):
|
||
"""将元素数据保存为CSV文件"""
|
||
if not elements_data:
|
||
print("没有元素数据可保存")
|
||
return False
|
||
|
||
try:
|
||
with open(output_path, 'w', newline='', encoding='utf-8-sig') as csvfile:
|
||
# 获取所有可能的字段名
|
||
all_fields = set()
|
||
for element in elements_data:
|
||
all_fields.update(element.keys())
|
||
|
||
fieldnames = sorted(list(all_fields))
|
||
|
||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||
writer.writeheader()
|
||
|
||
for element in elements_data:
|
||
# 确保所有字段都有值
|
||
row = {}
|
||
for field in fieldnames:
|
||
row[field] = element.get(field, '')
|
||
writer.writerow(row)
|
||
|
||
print(f"元素数据已保存到: {output_path}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"保存CSV文件失败: {e}")
|
||
return False
|
||
|
||
def save_elements_to_json(elements_data, output_path):
|
||
"""将元素数据保存为JSON文件"""
|
||
if not elements_data:
|
||
print("没有元素数据可保存")
|
||
return False
|
||
|
||
try:
|
||
with open(output_path, 'w', encoding='utf-8') as jsonfile:
|
||
json.dump(elements_data, jsonfile, ensure_ascii=False, indent=2)
|
||
|
||
print(f"元素数据已保存到: {output_path}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"保存JSON文件失败: {e}")
|
||
return False
|
||
|
||
def create_summary_report(elements_data, output_path, target_color):
|
||
"""创建元素统计报告"""
|
||
if not elements_data:
|
||
return False
|
||
|
||
try:
|
||
with open(output_path, 'w', encoding='utf-8') as report:
|
||
report.write("DWG文件特定颜色元素提取报告\n")
|
||
report.write("=" * 50 + "\n\n")
|
||
|
||
report.write(f"目标颜色: RGB({target_color[0]}, {target_color[1]}, {target_color[2]})\n")
|
||
report.write(f"总元素数量: {len(elements_data)}\n\n")
|
||
|
||
# 按类型统计
|
||
type_count = {}
|
||
layer_count = {}
|
||
|
||
for element in elements_data:
|
||
# 类型统计
|
||
element_type = element.get('element_type', 'Unknown')
|
||
type_count[element_type] = type_count.get(element_type, 0) + 1
|
||
|
||
# 图层统计
|
||
layer = element.get('layer_name', 'Unknown')
|
||
layer_count[layer] = layer_count.get(layer, 0) + 1
|
||
|
||
# 写入统计信息
|
||
report.write("按类型统计:\n")
|
||
for element_type, count in sorted(type_count.items()):
|
||
report.write(f" {element_type}: {count}\n")
|
||
|
||
report.write("\n按图层统计:\n")
|
||
for layer, count in sorted(layer_count.items()):
|
||
report.write(f" {layer}: {count}\n")
|
||
|
||
# 长度统计
|
||
lengths = [element.get('length', 0) for element in elements_data if 'length' in element and element['length'] > 0]
|
||
if lengths:
|
||
report.write(f"\n长度统计:\n")
|
||
report.write(f" 最短元素: {min(lengths):.4f}\n")
|
||
report.write(f" 最长元素: {max(lengths):.4f}\n")
|
||
report.write(f" 平均长度: {sum(lengths)/len(lengths):.4f}\n")
|
||
|
||
# 详细数据
|
||
report.write(f"\n详细元素数据:\n")
|
||
for i, element in enumerate(elements_data):
|
||
report.write(f"\n元素 {i+1}:\n")
|
||
for key, value in element.items():
|
||
report.write(f" {key}: {value}\n")
|
||
|
||
print(f"统计报告已保存到: {output_path}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"创建统计报告失败: {e}")
|
||
return False
|
||
|
||
def main():
|
||
"""主函数"""
|
||
print_separator("DWG文件特定颜色元素提取工具")
|
||
print("提取颜色为(0, 255, 255)的所有元素")
|
||
print()
|
||
|
||
# 目标颜色 (青色)
|
||
target_color = (0, 255, 255)
|
||
|
||
# 查找DWG文件
|
||
dwg_files = list(Path('.').glob('*.dwg'))
|
||
|
||
if not dwg_files:
|
||
print("当前目录下未找到DWG文件")
|
||
print("请确保DWG文件在当前目录中")
|
||
return
|
||
|
||
print(f"找到 {len(dwg_files)} 个DWG文件:")
|
||
for i, dwg_file in enumerate(dwg_files, 1):
|
||
print(f" {i}. {dwg_file}")
|
||
|
||
# 优先使用测试图纸文件
|
||
test_file = None
|
||
for dwg_file in dwg_files:
|
||
if '测试图纸文件' in str(dwg_file):
|
||
test_file = str(dwg_file)
|
||
break
|
||
|
||
if not test_file:
|
||
test_file = str(dwg_files[0])
|
||
|
||
print(f"\n使用文件进行提取: {test_file}")
|
||
|
||
# 提取特定颜色元素
|
||
elements_data = extract_color_elements_simple(test_file, target_color)
|
||
|
||
if elements_data is None:
|
||
print("元素提取失败")
|
||
return
|
||
|
||
# 保存数据
|
||
base_name = test_file.replace('.dwg', '')
|
||
|
||
# 保存为CSV
|
||
csv_path = f"{base_name}_color_elements.csv"
|
||
csv_success = save_elements_to_csv(elements_data, csv_path)
|
||
|
||
# 保存为JSON
|
||
json_path = f"{base_name}_color_elements.json"
|
||
json_success = save_elements_to_json(elements_data, json_path)
|
||
|
||
# 创建统计报告
|
||
report_path = f"{base_name}_color_elements_report.txt"
|
||
report_success = create_summary_report(elements_data, report_path, target_color)
|
||
|
||
# 总结
|
||
print_separator("提取总结")
|
||
print(f"提取的元素数量: {len(elements_data)}")
|
||
print(f"CSV文件保存: {'成功' if csv_success else '失败'}")
|
||
print(f"JSON文件保存: {'成功' if json_success else '失败'}")
|
||
print(f"统计报告生成: {'成功' if report_success else '失败'}")
|
||
|
||
if csv_success or json_success:
|
||
print(f"\n元素提取完成!文件已保存到当前目录")
|
||
print(f" - CSV文件: {csv_path}")
|
||
print(f" - JSON文件: {json_path}")
|
||
print(f" - 统计报告: {report_path}")
|
||
else:
|
||
print("\n所有保存操作都失败了")
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
main()
|
||
except KeyboardInterrupt:
|
||
print("\n\n用户中断了程序执行")
|
||
except Exception as e:
|
||
print(f"\n\n程序执行出错: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|