Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python PIL中缩放和裁剪图像,但不超过图像尺寸_Python_Python Imaging Library_Crop_Image Scaling - Fatal编程技术网

在python PIL中缩放和裁剪图像,但不超过图像尺寸

在python PIL中缩放和裁剪图像,但不超过图像尺寸,python,python-imaging-library,crop,image-scaling,Python,Python Imaging Library,Crop,Image Scaling,我正在使用python PIL裁剪图像。假设我的形象是这样的: 这是我用于裁剪的简单代码段: from PIL import Image im = Image.open(image) cropped_image = im.crop((topLeft_x, topLeft_y, bottomRight_x, bottomRight_y)) cropped_image.save("Out.jpg") 其结果是: 我想缩小这个裁剪过的图像,保持纵横比(宽度和高度的比例)不变,比如说20%,这样看

我正在使用python PIL裁剪图像。假设我的形象是这样的:

这是我用于裁剪的简单代码段:

from PIL import Image
im = Image.open(image)
cropped_image = im.crop((topLeft_x, topLeft_y, bottomRight_x, bottomRight_y))
cropped_image.save("Out.jpg")
其结果是:

我想缩小这个裁剪过的图像,保持纵横比(宽度和高度的比例)不变,比如说20%,这样看起来就不会超过图像的尺寸


我应该如何缩放裁剪,以便在不超过图像边界/尺寸的情况下保持纵横比?

您应该计算裁剪的中心并在那里使用它。 例如:

crop_width = right - left
crop_height = bottom - top
crop_center_x = int(left + crop_width/2)
crop_center_y = (top + crop_height/2)
通过这种方式,您将获得(x,y)点,该点与原始图像的裁剪中心w.r.t相对应。 在这种情况下,您将知道裁剪的最大宽度是原始图像的中心值和外部边界之间的最小值减去中心本身:

im = Image.open("brad.jpg")
l = 200
t = 200
r = 300
b = 300
cropped = im.crop((l, t, r, b))
这给了你:

如果您希望从同一中心开始将其“放大”到最大值,则您将拥有:

max_width = min(crop_center_x, im.size[0]-crop_center_x)
max_height = min(crop_center_y, im.size[1]-crop_center_y)
new_l = crop_center_x - max_width
new_t = crop_center_x - max_height
new_r = crop_center_x + max_width
new_b = crop_center_x + max_height
new_crop = im.crop((new_l, new_t, new_r, new_b))
其结果是,具有相同的中心:


编辑 如果要保留纵横比,则应在之前检索纵横比(该比率),并仅在生成的大小仍适合原始图像时应用裁剪。例如,如果您想将其放大20%:

ratio = crop_height/crop_width
scale = 20/100
new_width = int(crop_width + (crop_width*scale))

# Here we are using the previously calculated value for max_width to 
# determine if the new one would be too large.
# Note that the width that we calculated here (new_width) refers to both
# sides of the crop, while the max_width calculated previously refers to
# one side only; same for height. Sorry for the confusion.
if max_width < new_width/2:
    new_width = int(2*max_width)

new_height = int(new_width*ratio)

# Do the same for the height, update width if necessary
if max_height < new_height/2:
    new_height = int(2*max_height)
    new_width = int(new_height/ratio)

adjusted_scale = (new_width - crop_width)/crop_width

if adjusted_scale != scale:
    print("Scale adjusted to: {:.2f}".format(adjusted_scale))

new_l = int(crop_center_x - new_width/2)
new_r = int(crop_center_x + new_width/2)
new_t = int(crop_center_y - new_height/2)
new_b = int(crop_center_y + new_height/2)
比率=裁剪高度/裁剪宽度
比例=20/100
新宽度=整数(裁剪宽度+(裁剪宽度*比例))
#这里我们使用先前计算的最大宽度值
#确定新的是否太大。
#请注意,我们在这里计算的宽度(new_width)指的是两者
#作物的侧面,而先前计算的最大_宽度指的是
#只有一面;身高也一样。很抱歉给你带来了困惑。
如果最大宽度<新宽度/2:
新宽度=整数(2*最大宽度)
新高度=整数(新宽度*比率)
#对高度执行相同操作,必要时更新宽度
如果最大高度<新高度/2:
新高度=整数(2*最大高度)
新宽度=整数(新高度/比率)
调整后的_比例=(新_宽度-裁剪_宽度)/裁剪_宽度
如果调整了刻度!=比例:
打印(“比例调整为:{.2f}”。格式(调整后的比例))
新高度=整数(裁剪中心高度-新宽度/2)
新宽度=整数(裁剪中心+新宽度/2)
新高度=整数(裁剪中心-新高度/2)
新高度=整数(裁剪中心+新高度/2)

获得宽度和高度值后,获得裁剪的过程与上述过程相同。

您实际上不是裁剪然后缩放裁剪的零件。真的,你的作物要大一些,不是吗?试着计算出作物的宽度和高度,以及x,y中心。对于新的裁剪,中心将是相同的,但宽度和高度将分别增加20%,即newwidth=1.2*oldwidth。这是一个不错的方法,但当它向外扩展时,会在超出图像的区域上添加一个黑色补丁。您可以在这里看到我对您的方法的实现(请参阅crop_face函数):以及此处的裁剪图像:。正如您将看到的,裁剪和缩放在顶部添加了一个黑色补丁。我们如何避免这种情况?一个明显的方法是减少缩放,但我想明智地做到这一点。只有当裁剪的图像比例超过原始图像尺寸时,我才想减小缩放比例。当然,我的不好。首先,应在裁剪中心x+新宽度/2(高度也是如此)上进行检查,并且新宽度和新宽度需要更新为+-新宽度/2。此外,还应进行另一项检查,以确保新的_height/2@FlyingAura I已经更新了代码,现在它应该可以工作了。请注意最大宽度和新宽度之间的区别:前者是指每边的最大宽度,而后者是指cropIn的全局新宽度
max\u width=min(x,im.size[0]-x)
,这里的
x
crop\u center\u x
相同吗?另外,我们在哪里使用
调整后的\u量表
?我已根据您的回答对代码进行了更改,但结果仍然相同:我缺少什么?你能把代码片段贴出来吗?