Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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
Algorithm 将图像缩放到像素级_Algorithm_Graphics_Language Agnostic_Zooming - Fatal编程技术网

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()