Algorithm 将图像缩放到像素级
对于一个艺术项目,我要做的一件事就是将图像放大到一个特定的像素。我一直在揉下巴,希望能得到一些关于如何继续的建议 以下是输入参数:Algorithm 将图像缩放到像素级,algorithm,graphics,language-agnostic,zooming,Algorithm,Graphics,Language Agnostic,Zooming,对于一个艺术项目,我要做的一件事就是将图像放大到一个特定的像素。我一直在揉下巴,希望能得到一些关于如何继续的建议 以下是输入参数: Screen: sw - screen width sh - screen height Image: iw - image width ih - image height Pixel: px - x position of pixel in image py - y position of pixel in image Zoom: zf - zoom fac
Screen:
sw - screen width
sh - screen height
Image:
iw - image width
ih - image height
Pixel:
px - x position of pixel in image
py - y position of pixel in image
Zoom:
zf - zoom factor (0.0 to 1.0)
Background colour:
bc - background colour to use when screen and image aspect ratios are different
产出:
The zoomed image (no anti-aliasing)
The screen position/dimensions of the pixel we are zooming to.
When zf is 0 the image must fit the screen with correct aspect ratio.
When zf is 1 the selected pixel fits the screen with correct aspect ratio.
我的一个想法是使用povray之类的东西,将相机移向大图像纹理或某个库(例如pygame)进行缩放。有没有人想到用简单的伪代码做些更聪明的事情
为了使它更简单,您可以使图像和屏幕具有相同的纵横比。我可以接受
我会根据需要更新更多信息
更新
将已接受的答案转换为PHP
编辑:对于艺术项目,您可以检查此框架: 我将其设置为1D,首先编写从原始图像到缩放图像的直接变换,并使用您的约束: 由于需要线性变换,其形式如下: D(x)=a x+b 你想要: 对于z=0: D(px)=px D(px+1)=px+1 对于z=1: D(px)=0 D(px+1)=西南 这使得: 对于z=0:a=1,b=0,D(x)=x 对于z=1:a=sw,b=-sw。px,D(x)=sw.x-sw.px 对于所有z,使用以下两个的线性组合: D(x)=z(sw.x-sw.px)+(1-z)(x) D(x)=(z.sw+1-z).x-z.sw.px 现在编写反函数,从输出坐标中获取原始坐标: ID(xout)=(xout+z.sw.px)/(z.sw+1-z) 它允许您从输入图像填充输出图像。对于每个输出像素,值为OriginalPixel[ID(xout)](当ID(xout)不在[0..sw]中时,使用背景值)
对于2D来说,这个想法是相似的,但是保持纵横比需要更多的努力。如果我正确理解了您想要做的事情。
您可以在图形程序(如Gimp)中打开图像,将缩放级别设置为1并拍摄屏幕截图。然后增加缩放级别并再次拍摄屏幕截图等。然后使用mencoder从屏幕截图创建AVI。如果原始图像的颜色值以数组形式给出
image[x][y]
然后,缩放图像的颜色值
image[x+zf*(px-x)][y+zf*(py-y)]
关于窗口大小/图像大小-图像的初始准备应注意:将图像放大到不再适合窗口的程度,并用您喜欢的背景色填充剩余像素
在python中,您可以执行以下操作
def naivezoom(im, px, py, zf, bg):
out = Image.new(im.mode, im.size)
pix = out.load()
iw, ih = im.size
for x in range(iw):
for y in range(ih):
xorg = x + zf*(px - x)
yorg = y + zf*(py - y)
if xorg >= 0 and xorg < iw and yorg >= 0 and yorg < ih:
pix[x,y] = im.getpixel( (xorg , yorg) )
else:
pix[x,y] = bg
return out
从
import Image
编辑:
给定stackoverflow徽标,您将获得
对于zf=0.3,在点25,6附近
对于zf=0.96,在同一点附近
使用以下代码获得图像
#!/bin/env python
from Tkinter import *
import Image
import ImageTk
def naivezoom(im, p, zf, bg):
out = Image.new(im.mode, im.size)
pix = out.load()
iw, ih = im.size
for x in range(iw):
for y in range(ih):
xorg = x + zf*(p[0] - x)
yorg = y + zf*(p[1] - y)
if xorg >= 0 and xorg < iw and yorg >= 0 and yorg < ih:
pix[x,y] = im.getpixel( (xorg , yorg) )
else:
pix[x,y] = bg
return out
class NaiveTkZoom:
def __init__(self, parent=None):
root = Tk()
self.im = Image.open('logo.jpg')
self.zf = 0.0
self.deltazf = 0.02
self.p = ( 0.1*self.im.size[0],0.1*self.im.size[1])
self.bg = 255
canvas = Canvas(root, width=self.im.size[0]+20 , height=self.im.size[1]+20)
canvas.pack()
root.bind('<Key>', self.onKey)
self.canvas = canvas
self.photo = ImageTk.PhotoImage(self.im)
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
def onKey(self, event):
if event.char == "+":
if self.zf < 1:
self.zf += self.deltazf
elif event.char == "-":
if self.zf > 0:
self.zf -= self.deltazf
self.out = naivezoom(self.im, self.p, self.zf, self.bg)
self.photo = ImageTk.PhotoImage(self.out)
self.canvas.delete(self.item)
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
print self.p, self.zf
if __name__ == "__main__":
NaiveTkZoom()
mainloop()
#/bin/env python
从Tkinter进口*
导入图像
导入ImageTk
def缩放(im、p、zf、bg):
输出=图像。新建(即时模式,即时大小)
pix=out.load()
iw,ih=im尺寸
对于范围内的x(iw):
对于范围内的y(ih):
xorg=x+zf*(p[0]-x)
yorg=y+zf*(p[1]-y)
如果xorg>=0且xorg=0且yorg0:
self.zf-=self.deltazf
self.out=naivezoom(self.im、self.p、self.zf、self.bg)
self.photo=ImageTk.PhotoImage(self.out)
self.canvas.delete(self.item)
self.item=self.canvas.create_image(10,10,anchor=NW,image=self.photo)
打印self.p,self.zf
如果名称=“\uuuuu main\uuuuuuuu”:
NavetkZoom()
mainloop()
使用的库和逐像素的方法并不是世界上最快的,但可以提供足够的材料供您使用
而且上面的代码不是很干净
编辑2(和3,公式居中):
这是另一个尝试,补充了翻译,但我感觉这也不是最终的(没有时间检查公式)。此外,平移的速度是恒定的,但这可能会导致缩放速度变慢并显示背景(如果缩放到的点太靠近边缘)。我还在原始图像上添加了一个点,这样就可以看到使用它所发生的事情,而无需在原始图像上绘制
#!/bin/env python
from Tkinter import *
import Image
import ImageTk
def markImage(im, p, bg):
pix = im.load()
pix[ p[0], p[1] ] = bg
def naiveZoom(im, p, zf, bg):
out = Image.new(im.mode, im.size)
pix = out.load()
iw, ih = im.size
for x in range(iw):
for y in range(ih):
xorg = x + zf*(p[0]+0.5-x) + zf*(1-zf)*(p[0]-iw/2)
yorg = y + zf*(p[1]+0.5-y) + zf*(1-zf)*(p[1]-ih/2)
if xorg >= 0 and xorg < iw and yorg >= 0 and yorg < ih:
pix[x,y] = im.getpixel( (xorg , yorg) )
else:
pix[x,y] = bg
return out
class NaiveTkZoom:
def __init__(self, parent=None):
root = Tk()
self.im = Image.open('py.jpg')
self.zf = 0.0
self.deltazf = 0.05
self.p = (round(0.3*self.im.size[0]), round(0.3*self.im.size[1]) )
self.bg = 255
markImage(self.im, self.p, self.bg)
canvas = Canvas(root, width=self.im.size[0]+20 , height=self.im.size[1]+20)
canvas.pack()
root.bind('<Key>', self.onKey)
self.canvas = canvas
self.photo = ImageTk.PhotoImage(self.im)
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
self.change = False
def onKey(self, event):
if event.char == "+":
if self.zf < 1:
self.zf += self.deltazf
self.change = True
elif event.char == "-":
if self.zf > 0:
self.zf -= self.deltazf
self.change = True
if self.change:
self.out = naiveZoom(self.im, self.p, self.zf, self.bg)
self.photo = ImageTk.PhotoImage(self.out)
self.canvas.delete(self.item)
self.change = False
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
print self.p, self.zf
if __name__ == "__main__":
NaiveTkZoom()
mainloop()
#/bin/env python
从Tkinter进口*
导入图像
导入ImageTk
def标记图像(im、p、bg):
pix=im.load()
pix[p[0],p[1]]=bg
def缩放(im、p、zf、bg):
输出=图像。新建(即时模式,即时大小)
pix=out.load()
iw,ih=im尺寸
对于范围内的x(iw):
对于范围内的y(ih):
xorg=x+zf*(p[0]+0.5-x)+zf*(1-zf)*(p[0]-iw/2)
yorg=y+zf*(p[1]+0.5-y)+zf*(1-zf)*(p[1]-ih/2)
如果xorg>=0且xorg=0且yorg#!/bin/env python
from Tkinter import *
import Image
import ImageTk
def markImage(im, p, bg):
pix = im.load()
pix[ p[0], p[1] ] = bg
def naiveZoom(im, p, zf, bg):
out = Image.new(im.mode, im.size)
pix = out.load()
iw, ih = im.size
for x in range(iw):
for y in range(ih):
xorg = x + zf*(p[0]+0.5-x) + zf*(1-zf)*(p[0]-iw/2)
yorg = y + zf*(p[1]+0.5-y) + zf*(1-zf)*(p[1]-ih/2)
if xorg >= 0 and xorg < iw and yorg >= 0 and yorg < ih:
pix[x,y] = im.getpixel( (xorg , yorg) )
else:
pix[x,y] = bg
return out
class NaiveTkZoom:
def __init__(self, parent=None):
root = Tk()
self.im = Image.open('py.jpg')
self.zf = 0.0
self.deltazf = 0.05
self.p = (round(0.3*self.im.size[0]), round(0.3*self.im.size[1]) )
self.bg = 255
markImage(self.im, self.p, self.bg)
canvas = Canvas(root, width=self.im.size[0]+20 , height=self.im.size[1]+20)
canvas.pack()
root.bind('<Key>', self.onKey)
self.canvas = canvas
self.photo = ImageTk.PhotoImage(self.im)
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
self.change = False
def onKey(self, event):
if event.char == "+":
if self.zf < 1:
self.zf += self.deltazf
self.change = True
elif event.char == "-":
if self.zf > 0:
self.zf -= self.deltazf
self.change = True
if self.change:
self.out = naiveZoom(self.im, self.p, self.zf, self.bg)
self.photo = ImageTk.PhotoImage(self.out)
self.canvas.delete(self.item)
self.change = False
self.item = self.canvas.create_image(10, 10, anchor=NW, image=self.photo)
print self.p, self.zf
if __name__ == "__main__":
NaiveTkZoom()
mainloop()