프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / potrace.py @ f145d925

이력 | 보기 | 이력해설 | 다운로드 (3.69 KB)

1
#!/usr/bin/env/python3
2
# coding: utf-8
3

    
4
import re
5
import numpy as np, cv2, subprocess
6
import os, sys
7
from xml.dom import minidom
8
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree
9
import xml.etree.ElementTree as ET
10
import SymbolBase
11
from shapely.geometry import LineString
12
from shapely.ops import linemerge
13
from LineDetector import LineDetector
14

    
15
# potrace command
16
POTRACE = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'potrace.exe')
17
ADJUST = 10
18

    
19
def convertImageToSvg(imgFilePath, destFilePath, normalColor, hoverColor, threshold=200):
20
    """convert image to svg file by using potrace"""
21

    
22
    image = cv2.imread(imgFilePath, cv2.IMREAD_GRAYSCALE)
23
    threshold = cv2.threshold(image, threshold, 255, cv2.THRESH_BINARY)[1]
24

    
25
    # convert to bmp binary so that potrace can handle it
26
    retval, buf = cv2.imencode('.bmp', threshold)
27
    if not retval:
28
        raise ValueError('Failed to convert into BMP binary data')
29
    # convert buf from numpy.ndarray to bytes
30
    binbmp = buf.tobytes()
31
    
32
    args = [
33
        POTRACE,
34
        '-', '-o-', '--svg'
35
    ]
36
    
37
    CREATE_NO_WINDOW = 0x08000000
38

    
39
    p = subprocess.Popen(
40
        args,
41
        stdin=subprocess.PIPE,
42
        stdout=subprocess.PIPE,
43
        stderr=subprocess.PIPE,
44
        creationflags=CREATE_NO_WINDOW
45
    )
46
        
47
    stdout, stderr = p.communicate(input=binbmp)
48
    if len(stderr) != 0:
49
        raise RuntimeError('Potrace threw error:\n' + stderr.decode('utf-8'))
50
    
51
    svgFile = open(destFilePath, "w")
52
    svgFile.write(stdout.decode("utf-8"))
53
    svgFile.close()
54

    
55
    ''' add lineargradient nodes to svg file '''
56
    try:
57
        doc = ET.parse(destFilePath)
58
        svg = doc.getroot()
59
        matches = [child for child in svg.getchildren() if re.search(re.compile('^\{.+\}g$'), child.tag)]
60
        if matches:
61
            matches[0].attrib['fill'] = 'url(#normal)'
62
            matches[0].attrib['stroke'] = 'url(#normal)'
63

    
64
            pathes = [child for child in matches[0].getchildren() if re.search(re.compile('^\{.+\}path$'), child.tag)]
65
            for path in pathes:
66
                path.attrib['stroke-width'] = '50'
67

    
68
        defs = Element('defs')
69
        gradient = ET.fromstring(normalColor)
70
        gradient.attrib['id'] = 'normal'
71
        defs.append(gradient)
72
        gradient = ET.fromstring(hoverColor)
73
        gradient.attrib['id'] = 'hover'
74
        defs.append(gradient)
75
        svg.append(defs)
76
        
77
        ''' remove ns0 from xml '''
78
        with open(destFilePath, 'w') as svgFile:
79
            svgFile.write(ET.tostring(svg, encoding='utf-8').decode('utf-8').replace('ns0:', '').replace(':ns0', ''))
80
    except Exception as ex:
81
        from App import App
82
        from AppDocData import MessageType
83

    
84
        message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
85
        App.mainWnd().addMessage.emit(MessageType.Error, message)
86

    
87
if __name__ == '__main__':
88
    execpath = os.path.dirname(os.path.realpath(__file__))
89

    
90
    path = execpath + '\\res\\UY1-K-2007_P1_300dpi_black.png'
91
    #lines = linedraw.sketch(path)
92
    #linedraw.visualize(lines)
93
#    path = sys.argv[1]  # 1 argument given is a string for the path of drawing
94
    #imgLines = passpotrace(path)    #execpath + '\\res\\UY1-K-2007_P1_300dpi_black.png')
95
    image  = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
96
    lineDetector = LineDetector(image)
97
    lineDetector.Detect()
98
    
99
    try:
100
        xmlFilePath = os.path.dirname(path) + '\\' + os.path.basename(path).split('.')[0] + '.xml'
101
        file = open(xmlFilePath, 'w')
102
        for line in imgLines:
103
            file.write(str(line) + '\n')
104
        file.close()
105
    except Exception as ex:
106
        print('에러가 발생했습니다.\n', ex)
클립보드 이미지 추가 (최대 크기: 500 MB)