개정판 f7940a95
issue #1363: implemented class to export svg
Change-Id: Ic3a8c972612a7db2f5b78034e423b64bbb7f8860
DTI_PID/DTI_PID/Commands/ExportCommand.py | ||
---|---|---|
3 | 3 |
import os.path |
4 | 4 |
import sys |
5 | 5 |
from enum import Enum |
6 |
import AbstractCommand |
|
6 | 7 |
from PyQt5.QtCore import * |
7 | 8 |
from PyQt5.QtGui import * |
8 | 9 |
from PyQt5.QtWidgets import * |
9 | 10 |
|
10 | 11 |
|
11 |
class ExportCommand(QThread):
|
|
12 |
class ExportCommand(AbstractCommand.AbstractCommand):
|
|
12 | 13 |
display_message = pyqtSignal(Enum, str) |
13 | 14 |
show_progress = pyqtSignal(int) |
14 | 15 |
|
15 |
def __init__(self, format): |
|
16 |
QThread.__init__(self)
|
|
16 |
def __init__(self, scene, format):
|
|
17 |
super(ExportCommand, self).__init__(None)
|
|
17 | 18 |
|
19 |
self._scene = scene |
|
18 | 20 |
self._format = format # xml, svg, image |
19 | 21 |
|
20 |
def __del__(self): |
|
21 |
self.wait() |
|
22 |
|
|
23 |
def run(self): |
|
22 |
def execute(self, param) -> bool: |
|
24 | 23 |
""" do given work""" |
25 | 24 |
from AppDocData import AppDocData |
26 | 25 |
from AppDocData import MessageType |
27 | 26 |
|
28 | 27 |
try: |
29 | 28 |
app_doc_data = AppDocData.instance() |
29 |
if self._format == 'svg': |
|
30 |
self.export_as_svg(param) |
|
31 |
elif self._format == 'xml': |
|
32 |
pass |
|
33 |
elif self._format == 'image': |
|
34 |
self.export_as_image(param) |
|
35 |
|
|
36 |
return True |
|
30 | 37 |
except Exception as ex: |
31 | 38 |
from AppDocData import MessageType |
32 | 39 |
|
... | ... | |
34 | 41 |
sys.exc_info()[-1].tb_lineno) |
35 | 42 |
self.display_message.emit(MessageType.Error, message) |
36 | 43 |
|
44 |
return False |
|
45 |
|
|
46 |
def prettify(self, elem): |
|
47 |
"""Return a pretty-printed XML string for the Element.""" |
|
48 |
from xml.etree import ElementTree |
|
49 |
from xml.dom import minidom |
|
50 |
|
|
51 |
rough_string = ElementTree.tostring(elem, 'utf-8') |
|
52 |
reparsed = minidom.parseString(rough_string) |
|
53 |
return reparsed.toprettyxml(indent=" ") |
|
54 |
|
|
55 |
def export_as_svg(self, file_path): |
|
56 |
"""export to svg file""" |
|
57 |
from xml.etree.ElementTree import Element, tostring, SubElement, dump, ElementTree, parse |
|
58 |
|
|
59 |
if not file_path: |
|
60 |
options = QFileDialog.Options() |
|
61 |
options |= QFileDialog.DontUseNativeDialog |
|
62 |
file_path, _ = QFileDialog.getSaveFileName(self, "Export as svg", os.getcwd(), "svg file(*.svg)", |
|
63 |
options=options) |
|
64 |
if file_path: |
|
65 |
file_name, ext = os.path.splitext(file_path) |
|
66 |
save_file_path = file_name + ext if ext.upper() == '.SVG' else file_name + '.svg' |
|
67 |
|
|
68 |
rect = self._scene.sceneRect() |
|
69 |
|
|
70 |
svg = Element('svg') |
|
71 |
svg.attrib['width'] = f"{rect.width()}" |
|
72 |
svg.attrib['height'] = f"{rect.height()}" |
|
73 |
svg.attrib['viewBox'] = f"{0} {0} {rect.width()} {rect.height()}" |
|
74 |
svg.attrib['xmlns'] = 'http://www.w3.org/2000/svg' |
|
75 |
svg.attrib['xmlns:xlink'] = "http://www.w3.org/1999/xlink" |
|
76 |
svg.attrib['version'] = "1.2" |
|
77 |
svg.attrib['baseProfile'] = "tiny" |
|
78 |
for item in self._scene.items(): |
|
79 |
if hasattr(item, 'to_svg'): |
|
80 |
node = item.to_svg() |
|
81 |
if node: |
|
82 |
svg.append(node) |
|
83 |
|
|
84 |
with open(save_file_path, 'w', encoding='utf-8') as output_file: |
|
85 |
output_file.write(self.prettify(svg)) |
|
86 |
|
|
87 |
def export_as_image(self, file_path): |
|
88 |
"""export to image file""" |
|
89 |
|
|
90 |
if not file_path: |
|
91 |
options = QFileDialog.Options() |
|
92 |
options |= QFileDialog.DontUseNativeDialog |
|
93 |
file_path, _ = QFileDialog.getSaveFileName(self, "Export as png", os.getcwd(), "png file(*.png)", |
|
94 |
options=options) |
|
95 |
if file_path: |
|
96 |
file_name, ext = os.path.splitext(file_path) |
|
97 |
save_file_path = file_name + ext if ext.upper() == '.PNG' else file_name + '.png' |
|
98 |
|
|
99 |
rect = self._scene.sceneRect() |
|
100 |
size = QSize(rect.width(), rect.height()) |
|
101 |
image = QImage(size, QImage.Format_ARGB32_Premultiplied) |
|
102 |
|
|
103 |
painter = QPainter(image) |
|
104 |
# render the scene |
|
105 |
self._scene.render(painter) |
|
106 |
painter.end() |
|
107 |
|
|
108 |
# save the image to a given file |
|
109 |
image.save(save_file_path) |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
1342 | 1342 |
self.graphicsView.scene.update(self.graphicsView.sceneRect()) |
1343 | 1343 |
DisplayColors.instance().save_data() |
1344 | 1344 |
|
1345 |
''' |
|
1346 |
@brief Open image drawing file and then display it |
|
1347 |
@author humkyung |
|
1348 |
@date 2018.??.?? |
|
1349 |
@history 18.04.23 Jeongwoo Add AppDocData.instance().setCurrentPidSource |
|
1350 |
18.04.23 Jeongwoo Add Store Set Current Pid Image on AppDocData |
|
1351 |
18.05.02 Jeongwoo Add useDefaultCommand() |
|
1352 |
humkyung 2018.05.24 load recognition result file if exists |
|
1353 |
Jeongwoo 2018.05.29 load data on xml if xml file exist |
|
1354 |
humkyung 2018.08.22 clear scene before loading xml file |
|
1355 |
''' |
|
1356 |
|
|
1357 | 1345 |
def open_image_drawing(self, drawing): |
1346 |
"""open and display image drawing file""" |
|
1358 | 1347 |
from Drawing import Drawing |
1359 | 1348 |
|
1360 | 1349 |
try: |
... | ... | |
1400 | 1389 |
if self.graphicsView.scene.receivers(self.graphicsView.scene.contents_changed) > 0: |
1401 | 1390 |
self.graphicsView.scene.contents_changed.disconnect() |
1402 | 1391 |
|
1392 |
SymbolSvgItem.DOCUMENTS.clear() |
|
1393 |
|
|
1403 | 1394 |
# Load data |
1404 | 1395 |
path = os.path.join(app_doc_data.getCurrentProject().getTempPath(), app_doc_data.imgName + '.xml') |
1405 | 1396 |
configs = app_doc_data.getConfigs('Data Load', 'Xml First') |
... | ... | |
1425 | 1416 |
|
1426 | 1417 |
return self.path |
1427 | 1418 |
|
1428 |
def prettify(self, elem): |
|
1429 |
"""Return a pretty-printed XML string for the Element.""" |
|
1430 |
from xml.etree import ElementTree |
|
1431 |
from xml.dom import minidom |
|
1432 |
|
|
1433 |
rough_string = ElementTree.tostring(elem, 'utf-8') |
|
1434 |
reparsed = minidom.parseString(rough_string) |
|
1435 |
return reparsed.toprettyxml(indent=" ") |
|
1436 |
|
|
1437 | 1419 |
def export_as_svg(self): |
1438 | 1420 |
"""export scene to svg file""" |
1439 |
from xml.etree.ElementTree import Element, tostring, SubElement, dump, ElementTree, parse
|
|
1421 |
from ExportCommand import ExportCommand
|
|
1440 | 1422 |
|
1441 | 1423 |
options = QFileDialog.Options() |
1442 | 1424 |
options |= QFileDialog.DontUseNativeDialog |
1443 | 1425 |
file_path, _ = QFileDialog.getSaveFileName(self, "Export as svg", os.getcwd(), "svg file(*.svg)", |
1444 | 1426 |
options=options) |
1445 | 1427 |
if file_path: |
1446 |
try: |
|
1447 |
file_name, ext = os.path.splitext(file_path) |
|
1448 |
save_file_path = file_name + ext if ext.upper() == '.SVG' else file_name + '.svg' |
|
1449 |
|
|
1450 |
# hide image drawing |
|
1451 |
self.onViewImageDrawing(False) |
|
1452 |
|
|
1453 |
rect = self.graphicsView.scene.sceneRect() |
|
1454 |
|
|
1455 |
svg = Element('svg') |
|
1456 |
svg.attrib['width'] = f"{rect.width()}" |
|
1457 |
svg.attrib['height'] = f"{rect.height()}" |
|
1458 |
svg.attrib['viewBox'] = f"{0} {0} {rect.width()} {rect.height()}" |
|
1459 |
svg.attrib['xmlns'] = 'http://www.w3.org/2000/svg' |
|
1460 |
svg.attrib['xmlns:xlink'] = "http://www.w3.org/1999/xlink" |
|
1461 |
svg.attrib['version'] = "1.2" |
|
1462 |
svg.attrib['baseProfile'] = "tiny" |
|
1463 |
for item in self.graphicsView.scene.items(): |
|
1464 |
if hasattr(item, 'to_svg'): |
|
1465 |
node = item.to_svg() |
|
1466 |
if node: |
|
1467 |
svg.append(node) |
|
1468 |
|
|
1469 |
with open(save_file_path, 'w', encoding='utf-8') as output_file: |
|
1470 |
output_file.write(self.prettify(svg)) |
|
1471 |
|
|
1472 |
""" create a svg file by using QSvgGenerator of pyqt5 |
|
1473 |
svg_gen = QSvgGenerator() |
|
1474 |
|
|
1475 |
svg_gen.setFileName(save_file_path) |
|
1476 |
rect = self.graphicsView.scene.sceneRect() |
|
1477 |
svg_gen.setSize(QSize(rect.width(), rect.height())) |
|
1478 |
svg_gen.setViewBox(QRect(0, 0, rect.width(), rect.height())) |
|
1479 |
svg_gen.setTitle(self.tr("SVG Generator for ID2")) |
|
1480 |
svg_gen.setDescription(self.tr("An SVG drawing created by the SVG Generator.")) |
|
1481 |
|
|
1482 |
painter = QPainter(svg_gen) |
|
1483 |
self.graphicsView.scene.render(painter) |
|
1484 |
painter.end() |
|
1485 |
""" |
|
1486 |
|
|
1487 |
QMessageBox.information(None, self.tr('Information'), self.tr('Successfully export to svg file')) |
|
1488 |
finally: |
|
1489 |
if self.actionImage_Drawing.isChecked(): |
|
1490 |
self.onViewImageDrawing(True) |
|
1491 |
self.actionImage_Drawing.setChecked(True) |
|
1428 |
cmd = ExportCommand(self.graphicsView.scene, 'svg') |
|
1429 |
cmd.display_message.connect(self.onAddMessage) |
|
1430 |
if cmd.execute(file_path): |
|
1431 |
QMessageBox.information(self, self.tr('Information'), self.tr('Successfully export to svg file')) |
|
1432 |
else: |
|
1433 |
QMessageBox.information(self, self.tr('Error'), self.tr('Fail to export to svg file')) |
|
1492 | 1434 |
|
1493 | 1435 |
def export_as_xml(self): |
1494 | 1436 |
pass |
1495 | 1437 |
|
1496 | 1438 |
def export_as_image(self): |
1497 | 1439 |
"""export scene to image file""" |
1440 |
from ExportCommand import ExportCommand |
|
1498 | 1441 |
|
1499 | 1442 |
options = QFileDialog.Options() |
1500 | 1443 |
options |= QFileDialog.DontUseNativeDialog |
... | ... | |
1502 | 1445 |
options=options) |
1503 | 1446 |
if file_path: |
1504 | 1447 |
try: |
1505 |
file_name, ext = os.path.splitext(file_path) |
|
1506 |
save_file_path = file_name + ext if ext.upper() == '.PNG' else file_name + '.png' |
|
1507 |
|
|
1508 | 1448 |
# hide image drawing |
1509 | 1449 |
self.onViewImageDrawing(False) |
1510 | 1450 |
|
1511 |
rect = self.graphicsView.scene.sceneRect() |
|
1512 |
size = QSize(rect.width(), rect.height()) |
|
1513 |
image = QImage(size, QImage.Format_ARGB32_Premultiplied) |
|
1514 |
painter = QPainter(image) |
|
1515 |
|
|
1516 |
# render the scene |
|
1517 |
self.graphicsView.scene.render(painter) |
|
1518 |
painter.end() |
|
1451 |
cmd = ExportCommand(self.graphicsView.scene, 'image') |
|
1452 |
cmd.display_message.connect(self.onAddMessage) |
|
1519 | 1453 |
|
1520 |
# save the image to a given file
|
|
1521 |
image.save(save_file_path)
|
|
1522 |
|
|
1523 |
QMessageBox.information(None, self.tr('Information'), self.tr('Successfully export to image file'))
|
|
1454 |
if cmd.execute(file_path):
|
|
1455 |
QMessageBox.information(self, self.tr('Information'), self.tr('Successfully export to image file'))
|
|
1456 |
else: |
|
1457 |
QMessageBox.information(self, self.tr('Error'), self.tr('Fail to export to image file'))
|
|
1524 | 1458 |
finally: |
1525 | 1459 |
if self.actionImage_Drawing.isChecked(): |
1526 | 1460 |
self.onViewImageDrawing(True) |
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py | ||
---|---|---|
26 | 26 |
ZVALUE = 50 |
27 | 27 |
HOVER_COLOR = 'url(#hover)' |
28 | 28 |
|
29 |
DOCUMENTS = {} # store documents and renders for symbols |
|
30 |
|
|
29 | 31 |
''' |
30 | 32 |
@history 18.04.11 Jeongwoo Add Variable (Name, Type) |
31 | 33 |
18.05.11 Jeongwoo Declare variable self.color |
... | ... | |
80 | 82 |
try: |
81 | 83 |
app_doc_data = AppDocData.instance() |
82 | 84 |
svg = None |
83 |
if self.name: |
|
84 |
_, svg = app_doc_data.read_symbol_shape(self.name) |
|
85 |
|
|
86 |
if not svg and path and os.path.isfile(path): |
|
87 |
f = QFile(path) |
|
88 |
f.open(QIODevice.ReadOnly) |
|
89 |
svg = f.readAll() |
|
90 |
f.close() |
|
91 |
|
|
92 |
self._document = QDomDocument() |
|
93 |
self._document.setContent(svg) |
|
94 |
self._renderer = QSvgRenderer(self._document.toByteArray()) |
|
85 |
|
|
86 |
if path not in SymbolSvgItem.DOCUMENTS: |
|
87 |
if self.name: |
|
88 |
_, svg = app_doc_data.read_symbol_shape(self.name) |
|
89 |
|
|
90 |
if not svg and path and os.path.isfile(path): |
|
91 |
f = QFile(path) |
|
92 |
f.open(QIODevice.ReadOnly) |
|
93 |
svg = f.readAll() |
|
94 |
f.close() |
|
95 |
|
|
96 |
self._document = QDomDocument() |
|
97 |
self._document.setContent(svg) |
|
98 |
self._renderer = QSvgRenderer(self._document.toByteArray()) |
|
99 |
SymbolSvgItem.DOCUMENTS[path] = [self._document, self._renderer] |
|
100 |
else: |
|
101 |
self._document, self._renderer = SymbolSvgItem.DOCUMENTS[path] |
|
102 |
|
|
95 | 103 |
self.setSharedRenderer(self._renderer) |
96 |
#self.setCacheMode(QGraphicsItem.NoCache) |
|
97 | 104 |
|
98 | 105 |
self._color = self.get_attribute('fill') |
99 | 106 |
except Exception as ex: |
DTI_PID/DTI_PID/SymbolEditorDialog.py | ||
---|---|---|
620 | 620 |
else: |
621 | 621 |
return newName |
622 | 622 |
|
623 |
def makeSymbolData(self, width, height):
|
|
623 |
def make_symbol_data(self, width, height):
|
|
624 | 624 |
"""make a symbol object to save to database""" |
625 | 625 |
|
626 | 626 |
uid = -1 |
... | ... | |
631 | 631 |
|
632 | 632 |
index = self.ui.treeViewSymbolCategory.currentIndex() |
633 | 633 |
item = self.ui.treeViewSymbolCategory.model().itemFromIndex(index) |
634 |
category = item.parent().text() |
|
635 |
self.FILE_NUMBER = 0 |
|
636 |
lastName = "" |
|
637 |
if self.selectedSymbol is not None: |
|
638 |
lastName = self.selectedSymbol.getName() |
|
639 |
fileName = "" |
|
640 |
if name == lastName: |
|
641 |
fileName = name |
|
634 |
if item: |
|
635 |
category = item.parent().text() |
|
636 |
self.FILE_NUMBER = 0 |
|
637 |
lastName = "" |
|
638 |
if self.selectedSymbol is not None: |
|
639 |
lastName = self.selectedSymbol.getName() |
|
640 |
fileName = "" |
|
641 |
if name == lastName: |
|
642 |
fileName = name |
|
643 |
else: |
|
644 |
fileName = self.makeFileName(category, name, name) |
|
645 |
threshold = str(self.ui.spinBoxThreshold.value()) |
|
646 |
minMatchPoint = self.ui.minMatchPointLineEdit.text() |
|
647 |
rotationCount = int(self.ui.rotationCountSpinBox.value() / 90) |
|
648 |
ocrOption = 0 |
|
649 |
isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0 |
|
650 |
originalPoint = self.ui.originalPointLineEdit.text() |
|
651 |
connectionPoint = self.makeConnectionPointListString() |
|
652 |
baseSymbol = item.text() # self.ui.baseSymbolComboBox.currentText() |
|
653 |
additionalSymbol = self.makeAdditionalSymbolListString() |
|
654 |
isExceptDetect = 1 if self.ui.isExceptDetectCheckBox.isChecked() else 0 |
|
655 |
|
|
656 |
hasInstrumentLabel = self.ui.spinBoxhasInstrumentLabel.value() |
|
657 |
|
|
658 |
detectFlip = 1 if self.ui.makeFlipCheckBox.isChecked() else 0 |
|
659 |
|
|
660 |
convertedThreshold = int(threshold) / 100.0 |
|
661 |
|
|
662 |
imageWidth = width |
|
663 |
iamgeHeight = height |
|
664 |
|
|
665 |
text_areas = [] |
|
666 |
for row in range(self.ui.textAreaTableWidget.rowCount()): |
|
667 |
area = Area('Text Area') |
|
668 |
area.parse(self.ui.textAreaTableWidget.item(row, 0).text()) |
|
669 |
text_areas.append(area) |
|
670 |
|
|
671 |
self.newSym = symbol.SymbolBase(fileName, category, convertedThreshold, int(minMatchPoint), True, |
|
672 |
rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, |
|
673 |
baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid, |
|
674 |
imageWidth, iamgeHeight, detectFlip=detectFlip, text_area=text_areas) |
|
675 |
|
|
676 |
return self.newSym |
|
642 | 677 |
else: |
643 |
fileName = self.makeFileName(category, name, name) |
|
644 |
threshold = str(self.ui.spinBoxThreshold.value()) |
|
645 |
minMatchPoint = self.ui.minMatchPointLineEdit.text() |
|
646 |
rotationCount = int(self.ui.rotationCountSpinBox.value() / 90) |
|
647 |
ocrOption = 0 |
|
648 |
isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0 |
|
649 |
originalPoint = self.ui.originalPointLineEdit.text() |
|
650 |
connectionPoint = self.makeConnectionPointListString() |
|
651 |
baseSymbol = item.text() # self.ui.baseSymbolComboBox.currentText() |
|
652 |
additionalSymbol = self.makeAdditionalSymbolListString() |
|
653 |
isExceptDetect = 1 if self.ui.isExceptDetectCheckBox.isChecked() else 0 |
|
654 |
|
|
655 |
hasInstrumentLabel = self.ui.spinBoxhasInstrumentLabel.value() |
|
656 |
|
|
657 |
detectFlip = 1 if self.ui.makeFlipCheckBox.isChecked() else 0 |
|
658 |
|
|
659 |
convertedThreshold = int(threshold) / 100.0 |
|
660 |
|
|
661 |
imageWidth = width |
|
662 |
iamgeHeight = height |
|
663 |
|
|
664 |
text_areas = [] |
|
665 |
for row in range(self.ui.textAreaTableWidget.rowCount()): |
|
666 |
area = Area('Text Area') |
|
667 |
area.parse(self.ui.textAreaTableWidget.item(row, 0).text()) |
|
668 |
text_areas.append(area) |
|
669 |
|
|
670 |
self.newSym = symbol.SymbolBase(fileName, category, convertedThreshold, int(minMatchPoint), True, |
|
671 |
rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, |
|
672 |
baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid, |
|
673 |
imageWidth, iamgeHeight, detectFlip=detectFlip, text_area=text_areas) |
|
674 |
|
|
675 |
return self.newSym |
|
678 |
QMessageBox.warning(self, self.tr('Warning'), self.tr('Please select symbol category')) |
|
679 |
return None |
|
676 | 680 |
|
677 | 681 |
''' |
678 | 682 |
@brief Make AdditionalSymbol String |
... | ... | |
726 | 730 |
''' |
727 | 731 |
|
728 | 732 |
def accept(self): |
733 |
from SymbolSvgItem import SymbolSvgItem |
|
734 |
|
|
729 | 735 |
valid, exceptionMsg = self.isValidSymbolInfo() |
730 | 736 |
app_doc_data = AppDocData.instance() |
731 | 737 |
if valid: |
738 |
symbol_data = self.make_symbol_data(self.ui.imageView.image().width(), self.ui.imageView.image().height()) |
|
739 |
if not symbol_data: |
|
740 |
return |
|
741 |
|
|
732 | 742 |
if self.selectedSymbol is None: |
733 |
isSuccess, fileType, SymName, image_file_path = app_doc_data.insertSymbol( |
|
734 |
self.makeSymbolData(self.ui.imageView.image().width(), self.ui.imageView.image().height())) |
|
743 |
isSuccess, fileType, SymName, image_file_path = app_doc_data.insertSymbol(symbol_data) |
|
735 | 744 |
else: |
736 |
isSuccess, fileType, SymName, image_file_path = app_doc_data.updateSymbol( |
|
737 |
self.makeSymbolData(self.ui.imageView.image().width(), self.ui.imageView.image().height())) |
|
745 |
isSuccess, fileType, SymName, image_file_path = app_doc_data.updateSymbol(symbol_data) |
|
738 | 746 |
|
739 | 747 |
if isSuccess and not self.display: |
740 | 748 |
try: |
... | ... | |
759 | 767 |
potrace.convertImageToSvg(image_file_path, svg_file_path, normalColor=normal_color, |
760 | 768 |
hoverColor=hover_color) |
761 | 769 |
|
770 |
# del document for symbol |
|
771 |
if svg_file_path in SymbolSvgItem.DOCUMENTS: |
|
772 |
del SymbolSvgItem.DOCUMENTS[svg_file_path] |
|
773 |
# up to here |
|
774 |
|
|
762 | 775 |
app_doc_data.update_symbol_shape(SymName, image_file_path, svg_file_path, None) |
763 | 776 |
self.isAccepted = True |
764 | 777 |
if self.ui.checkBoxChange.isChecked(): |
DTI_PID/DTI_PID/potrace.py | ||
---|---|---|
75 | 75 |
svg.append(defs) |
76 | 76 |
|
77 | 77 |
''' remove ns0 from xml ''' |
78 |
svgFile = open(destFilePath, 'w') |
|
79 |
svgFile.write(ET.tostring(svg, encoding='utf-8').decode('utf-8').replace('ns0:', '').replace(':ns0', '')) |
|
80 |
svgFile.close() |
|
78 |
with open(destFilePath, 'w') as svgFile: |
|
79 |
svgFile.write(ET.tostring(svg, encoding='utf-8').decode('utf-8').replace('ns0:', '').replace(':ns0', '')) |
|
81 | 80 |
except Exception as ex: |
82 | 81 |
from App import App |
83 | 82 |
from AppDocData import MessageType |
내보내기 Unified diff