2009-03-18 14 views
6

Necesito transformar imágenes de mapa de bits con sus 4 puntos de esquina movidos de una ubicación a otra.imágenes de transformación de 4 puntos

Se aceptará cualquier código que pueda ejecutarse en Windows, preferiblemente C =/VB.NET, incluso ayuda con el uso de programas programables como Paint.NET o Photoshop. La API de Java Advanced Imaging suena optimista.

lo necesito para un sistema de captura de pantalla y la manipulación, que le permite obtener tales efectos:

alt text http://www.wholetomato.com/images/tour/mondoPerspectiveTrans.gif

Respuesta

1

Más fácil que simula una perspectiva distorsionar el uso de la manipulación de imágenes, se puede usar OpenGL o DirectX (XNA) a en realidad realizar la visualización en perspectiva.

Renderice un quad simple con su imagen como el mapa de texturas. Configura tu escena, renderiza en un buffer, y tienes tu imagen.

Actualización Resulta que XNA es una biblioteca ridícula (orientada a hacer juegos y nada más, bostezar). Managed DirectX requiere una lobotomía cerebral. OpenGL es fácil de usar, pero carece de código de carga de imágenes. Eso nos deja con WPF:

alt text http://praeclarum.org/so/persp.png

La imagen podría mejorarse forzando WPF en el modo anti-alias (¿por qué oh por qué Microsoft estás tan corto de vista?), Y al no utilizar Aero vidrio que las fuerzas ese borde negro de 1 píxel en todas las capturas de pantalla (o quitando ese borde de 1 píxel).

(Lo siento por la longitud de este código, pero WPF es una API hablador.)

public partial class Window1 : Window { 
    const float ANGLE = 30; 
    const float WIDTH = 8; 
    public Window1() { 
     InitializeComponent(); 

     var group = new Model3DGroup(); 
     group.Children.Add(Create3DImage(@"C:\Users\fak\Pictures\so2.png")); 
     group.Children.Add(new AmbientLight(Colors.White)); 

     ModelVisual3D visual = new ModelVisual3D(); 
     visual.Content = group; 
     viewport.Children.Add(visual); 
    } 

    private GeometryModel3D Create3DImage(string imgFilename) { 
     var image = LoadImage(imgFilename); 

     var mesh = new MeshGeometry3D(); 
     var height = (WIDTH * image.PixelHeight)/image.PixelWidth; 
     var w2 = WIDTH/2.0; 
     var h2 = height/2.0; 
     mesh.Positions.Add(new Point3D(-w2, -h2, 0)); 
     mesh.Positions.Add(new Point3D(w2, -h2, 0)); 
     mesh.Positions.Add(new Point3D(w2, h2, 0)); 
     mesh.Positions.Add(new Point3D(-w2, h2, 0)); 
     mesh.TriangleIndices.Add(0); 
     mesh.TriangleIndices.Add(1); 
     mesh.TriangleIndices.Add(2); 
     mesh.TriangleIndices.Add(0); 
     mesh.TriangleIndices.Add(2); 
     mesh.TriangleIndices.Add(3); 
     mesh.TextureCoordinates.Add(new Point(0, 1)); // 0, 0 
     mesh.TextureCoordinates.Add(new Point(1, 1)); 
     mesh.TextureCoordinates.Add(new Point(1, 0)); 
     mesh.TextureCoordinates.Add(new Point(0, 0)); 

     var mat = new DiffuseMaterial(new ImageBrush(image)); 
     mat.AmbientColor = Colors.White; 

     var geometry = new GeometryModel3D(); 
     geometry.Geometry = mesh; 
     geometry.Material = mat; 
     geometry.BackMaterial = mat; 

     geometry.Transform = new RotateTransform3D(
      new AxisAngleRotation3D(new Vector3D(0,1,0), ANGLE), 
      new Point3D(0, 0, 0)); 

     return geometry; 
    } 

    public static BitmapSource LoadImage(string filename) { 
     return BitmapDecoder.Create(new Uri(filename, UriKind.RelativeOrAbsolute), 
      BitmapCreateOptions.None, BitmapCacheOption.Default).Frames[0]; 
    } 
} 

Y el XAML requerido:

<Window x:Class="Persp.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Perspective Window" Height="480" Width="640"> 
<Grid> 
    <Viewport3D x:Name="viewport"> 
     <Viewport3D.Resources> 
     </Viewport3D.Resources> 
     <Viewport3D.Camera> 
      <PerspectiveCamera x:Name="cam" 
        FarPlaneDistance="100" 
        LookDirection="0,0,-1" 
        UpDirection="0,1,0" 
        NearPlaneDistance="1" 
        Position="0,0,10" 
        FieldOfView="60" /> 
     </Viewport3D.Camera> 
    </Viewport3D> 
</Grid> 
</Window> 
+0

El problema es, ¿cómo convertir los 4 puntos en una rotación 3D? –

2

La palabra clave aquí es homography. Manolis Lourakis ha escrito una implementación de homografía GPL en C que está disponible here; sin embargo, esto no se puede portar muy fácilmente porque se basa en algunas bibliotecas externas como LAPACK.

2

responsabilidad: Trabajo en Atalasoft

Si usted está dispuesto a ir comercial, DotImage de fotos puede hacer esto con la QuadrilateralWarpCommand. La muestra C# Código

// Load an image. 
AtalaImage image = new AtalaImage("test-image.jpg"); 

// Prepare the warp positions. 
Point bottomLeft = new Point(100, image.Height - 80); 
Point topLeft = new Point(130, 45); 
Point topRight = new Point(image.Width - 60, 140); 
Point bottomRight = new Point(image.Width - 20, image.Height); 

// Warp the image. 
QuadrilateralWarpCommand cmd = new QuadrilateralWarpCommand(bottomLeft, 
    topLeft, topRight, bottomRight, InterpolationMode.BiLinear, Color.White); 
AtalaImage result = cmd.Apply(image).Image; 

http://www.atalasoft.com/products/dotimage

+0

¿Es esto una deformación afín o una deformación en perspectiva? –

+0

No creo que pueda obtener esto con un warp Affine (al menos no 2d). Admitimos varias transformaciones afines comunes, y puede hacer su propia matriz 2D. No admitimos transformaciones 3D (que es lo que creo que necesitaría para hacer este tipo de transformación usando una matriz). –

Cuestiones relacionadas