-
I used 'Drawing / Export Addon' to produce a Raster image with dxf file and I extracted a line coordinate (dxf.start,dxf.end ) at the dxf file. In this sense, I would like to emphasize the line on the Raster image. However, I could not get the correct match on the raster image. In short, how can I convert the given line coordinate at dxf file to raster image coordinate? candidate_doc=ezdxf.readfile("MS201.dxf")
cndidate_msp=candidate_doc.modelspace()
candidate_lower_left=candidate_doc.header['$EXTMIN']
candidate_upper_right=candidate_doc.header['$EXTMAX']
dxf_width=candidate_upper_right[0]-candidate_lower_left[0]
dxf_height=candidate_upper_right[1]-candidate_lower_left[1] fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ctx = RenderContext(candidate_doc)
out = MatplotlibBackend(ax)
Frontend(ctx, out).draw_layout(candidate_msp, finalize=True)
fig.savefig('dxf_image.png', dpi=3000) line coordinates in WCS at dxf file: x1=line.dxf.start[0]
y1=line.dxf.start[1]
x2=line.dxf.end[0]
y2=line.dxf.end[1] The problem is in here. find_x1, find_y1, find_x2 and find_y2 are not the correct image coordinates. How can I get the correct pixel coordinates in this part? image = Image.open('dxf_image.png')
image_width ,image_height = image.size
find_x1= (image_width*x1)/dxf_width
find_y1=(image_height*y1)/dxf_height
find_x2=(image_width*x2)/dxf_width
find_y2=(image_height*y2)/dxf_height draw = ImageDraw.Draw(image)
draw.line((find_x1 ,-1*find_y1,find_x2,-1*find_y2),fill=128,width=120)
image.save('line.png') |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
the EXTMIN and EXTMAX header variables don't correspond to the limits of the drawing. They are just hints (and are usually wrong).
if you really do need to get the transformation from the data coordinates of the plot to the resulting image, you can use this approach: from __future__ import annotations
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw
import numpy as np
import ezdxf
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend
def transform_point(x:float, y: float, m: np.ndarray) -> tuple[float, float]:
return tuple((m @ [x, y, 1])[:2].tolist())
def translation_matrix(x: float, y: float) -> np.ndarray:
m = np.eye(3)
m[0, 2] = x
m[1, 2] = y
return m
def scale_matrix(x: float, y: float) -> np.ndarray:
return np.diag((x, y, 1))
def get_wcs_to_image_transform(ax: plt.Axes, image_size: tuple[int, int]) -> np.ndarray:
x1, x2 = ax.get_xlim()
y1, y2 = ax.get_ylim()
data_width, data_height = x2 - x1, y2 - y1
image_width, image_height = image_size
# +1 to counteract the effect of the pixels being flipped in y
return (translation_matrix(0, image_height + 1) @
scale_matrix(image_width / data_width, -image_height / data_height) @
translation_matrix(-x1, -y1))
def main():
doc = ezdxf.new()
layout = doc.modelspace()
layout.add_lwpolyline([(0, 0), (1, 0), (1, 1), (0, 1)], close=True)
layout.add_line((0, 0), (1, 1))
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ctx = RenderContext(doc)
out = MatplotlibBackend(ax)
Frontend(ctx, out).draw_layout(layout, finalize=True)
fig.savefig('cad.png')
plt.close(fig)
img = Image.open('cad.png')
draw = ImageDraw.Draw(img)
m = get_wcs_to_image_transform(ax, img.size)
print(m)
a = transform_point(0.25, 0.75, m)
b = transform_point(0.75, 0.25, m)
c = transform_point(1, 1, m)
draw.line(a + b, fill=(255, 0, 0))
draw.line(b + c, fill=(255, 0, 0))
draw.line(a + c, fill=(255, 0, 0))
img.show()
if __name__ == '__main__':
main() |
Beta Was this translation helpful? Give feedback.
the EXTMIN and EXTMAX header variables don't correspond to the limits of the drawing. They are just hints (and are usually wrong).
if you want to highlight a particular entity then there are several ways you could do that:
MatplotlibBackend
and create your own backend which takes a collection of entity handles that should be highlighted. Override thedraw_line
method to draw highlighted lines differently (useself.current_entity.dxf.handle
to get the handle of the line being drawn indraw_line
)ax.plot()
to draw over the cad before saving the image?if you real…