Python 在图像上画对角线
嗨,我正试图画一条从右上到左下的对角线,这是我的代码Python 在图像上画对角线,python,drawing,jython,jes,Python,Drawing,Jython,Jes,嗨,我正试图画一条从右上到左下的对角线,这是我的代码 width = getWidth(picture) height = getHeight(picture) for x in range(0, width): for y in range(0, height): pixel = getPixel(picture, x, y) setColor(pixel, black) 谢谢您的图片对象来自哪里?这是怎么一回事?到目前为止,什么不起作用?您正在尝
width = getWidth(picture)
height = getHeight(picture)
for x in range(0, width):
for y in range(0, height):
pixel = getPixel(picture, x, y)
setColor(pixel, black)
谢谢您的
图片
对象来自哪里?这是怎么一回事?到目前为止,什么不起作用?您正在尝试使用哪个图像访问库?(我的意思是,你从哪里获得或打算从哪里获得“getWidth、getHeight、getPixel、setColor”
我认为没有一个库可以为你提供一个“像素”作为一个整体对象,可以在setColor调用中使用,如果它真的存在,它将是世界上最慢的东西——也许是在银河系中
另一方面,如果这些方法确实存在,并且您的图片是黑色的,那么上面的代码将覆盖所有图像-您将在图像的所有可能的x值(从0到宽度)内获得所有可能的“y”值(从0到高度),并将每个图像着色
绘制直线需要同时更改x和y,更像:
(使用另一个“假想库”,但还有一个可能:
for x, y in zip(range(0, width), range(0, height)):
picture.setPixel((x,y), Black) )
这是可行的,但除非图像是完美的正方形,否则线条就不会完美——否则它会跳过图像最宽方向上的像素。要解决这个问题,需要一个更精确的算法——但这是第二个让你能够真正访问图像上像素的方法——就像使用Python的图像库(PIL或枕头),或pygame,或其他一些库。大多数图形库都有一些直接画线的方法 其中有
addLine
函数,因此您可以
addLine(picture, 0, 0, width, height)
如果你坚持设置单个像素,你应该看看,这是最有效的画线算法之一
代码需要注意的是:使用两个嵌套循环的操作如下
for each column in the picture
for each row in the current column
set the pixel in the current column and current row to black
因此,基本上你用黑色像素填充整个图像
编辑
要在整个图像上绘制多条对角线(在它们之间留一个空间),可以使用以下循环
width = getWidth(picture)
height = getHeight(picture)
space = 10
for x in range(0, 2*width, space):
addLine(picture, x, 0, x-width, height)
这将为您提供一个图像,如(示例为手绘…)
这利用了大多数图形库提供的剪裁功能,即不在图像内的线条部分被忽略。请注意,如果没有
2*宽度
(即如果x
,则只能使用),只有左上半部分的线条会被画出来…我想在讨论中添加一些数学方面的考虑
(只是因为遗憾的是JES的addLine函数只绘制了黑线,而且非常有限……)
注意:以下代码使用了MartinStettner
指出的Bresenham直线算法(多亏了他)
Bresenham直线算法是一种确定在两个给定点之间形成直线近似的顺序的算法。由于像素是一个原子实体,因此只能通过某种近似在计算机屏幕上绘制直线
注意:要理解以下代码,您需要记住一点基本的学校数学课程(直线方程和三角学)
代码:
#以下是快速实现,并包含副作用。。。
随机输入
#绘制点,并检查该点是否在图像区域中
def提取点(图、柱、x、y):
如果(x>=0)和(x=0)和(y-dy):
err=err-dy
x0=x0+sx
如果(x0==x1)和(y0==y1):
支点(pic、col、x0、y0)
打破
如果(e2b=y0-m*x0
b=y0-m*x0
x0=0
y0=int(m*x0+b)
#在远离第一分的地方获得第二分
x1=getWidth(图)
y1=int(m*x1+b)
抽绳(pic、col、x0、y0、x1、y1)
#从原点和角度画无限长的线
#角度“θ”以度表示
def绘图无穷远线(图、柱、x、y、θ):
#y=m*x+b
dx=y*tan(θ*pi/180.0)#(需要弧度)
dy=y
如果(dx==0):
dx+=0.000000001#避免被零除
m=dy/dx
#y=m*x+b=>b=y-m*x
b=y-m*x
#在远离第一分的地方获得第二分
x1=2*getWidth(图)
y1=m*x1+b
绘制无限线(图,柱,x,y,x1,y1)
#根据给定的偏移量和角度绘制多条平行线
def多行(pic、col、offset、θ、randOffset=0):
#覆盖整个表面的范围为[-2*宽度,2*宽度]
对于X范围内的i(-2*getWidth(pic),2*getWidth(pic),偏移量):
drawInfiniteLineA(pic,col,i+random.randint(0,randfost),1,θ)
#绘制多条线,给定偏移、角度和角度偏移
def多重信号(pic、col、offsetX、offsetY、θ、offsetA):
j=0
#覆盖整个表面的范围为[-2*宽度,2*宽度]
对于X范围内的i(-2*getWidth(pic),2*getWidth(pic),偏移量x):
绘制无限线图(图、列、i、j、θ)
j+=偏移
θ+=偏移量
file=pickAFile()
picture=makePicture(文件)
颜色=makeColor(0,65,65)#pickAColor()
#抽绳(图片,颜色,10,10,100,100)
#drawInfiniteLine(图片、颜色、10、10、100、100)
#drawInfiniteLineA(图片、颜色、50、50、135.0)
#多重
# The following is fast implementation and contains side effects...
import random
# Draw point, with check if the point is in the image area
def drawPoint(pic, col, x, y):
if (x >= 0) and (x < getWidth(pic)) and (y >= 0) and (y < getHeight(pic)):
px = getPixel(pic, x, y)
setColor(px, col)
# Draw line segment, given two points
# From Bresenham's line algorithm
# http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
def drawLine(pic, col, x0, y0, x1, y1):
dx = abs(x1-x0)
dy = abs(y1-y0)
sx = sy = 0
#sx = 1 if x0 < x1 else -1
#sy = 1 if y0 < y1 else -1
if (x0 < x1):
sx = 1
else:
sx = -1
if (y0 < y1):
sy = 1
else:
sy = -1
err = dx - dy
while (True):
drawPoint(pic, col, x0, y0)
if (x0 == x1) and (y0 == y1):
break
e2 = 2 * err
if (e2 > -dy):
err = err - dy
x0 = x0 + sx
if (x0 == x1) and (y0 == y1):
drawPoint(pic, col, x0, y0)
break
if (e2 < dx):
err = err + dx
y0 = y0 + sy
# Draw infinite line from segment
def drawInfiniteLine(pic, col, x0, y0, x1, y1):
# y = m * x + b
m = (y0-y1) / (x0-x1)
# y0 = m * x0 + b => b = y0 - m * x0
b = y0 - m * x0
x0 = 0
y0 = int(m*x0 + b)
# get a 2nd point far away from the 1st one
x1 = getWidth(pic)
y1 = int(m*x1 + b)
drawLine(pic, col, x0, y0, x1, y1)
# Draw infinite line from origin point and angle
# Angle 'theta' expressed in degres
def drawInfiniteLineA(pic, col, x, y, theta):
# y = m * x + b
dx = y * tan(theta * pi / 180.0) # (need radians)
dy = y
if (dx == 0):
dx += 0.000000001 # Avoid to divide by zero
m = dy / dx
# y = m * x + b => b = y - m * x
b = y - m * x
# get a 2nd point far away from the 1st one
x1 = 2 * getWidth(pic)
y1 = m*x1 + b
drawInfiniteLine(pic, col, x, y, x1, y1)
# Draw multiple parallele lines, given offset and angle
def multiLines(pic, col, offset, theta, randOffset = 0):
# Range is [-2*width, 2*width] to cover the whole surface
for i in xrange(-2*getWidth(pic), 2*getWidth(pic), offset):
drawInfiniteLineA(pic, col, i + random.randint(0, randOffset), 1, theta)
# Draw multiple lines, given offset, angle and angle offset
def multiLinesA(pic, col, offsetX, offsetY, theta, offsetA):
j = 0
# Range is [-2*width, 2*width] to cover the whole surface
for i in xrange(-2*getWidth(pic), 2*getWidth(pic), offsetX):
drawInfiniteLineA(pic, col, i, j, theta)
j += offsetY
theta += offsetA
file = pickAFile()
picture = makePicture(file)
color = makeColor(0, 65, 65) #pickAColor()
#drawline(picture, color, 10, 10, 100, 100)
#drawInfiniteLine(picture, color, 10, 10, 100, 100)
#drawInfiniteLineA(picture, color, 50, 50, 135.0)
#multiLines(picture, color, 20, 56.0)
#multiLines(picture, color, 10, 56.0, 15)
multiLinesA(picture, color, 10, 2, 1.0, 1.7)
show(picture)