2009-03-18 35 views
6

Tôi cần phải chuyển đổi hình ảnh bitmap với 4 điểm góc được di chuyển từ vị trí này sang vị trí khác.Hình ảnh biến đổi 4 điểm

Bất kỳ mã nào có thể chạy trên Windows, C#/VB.NET tốt hơn, thậm chí giúp cách sử dụng các chương trình có thể viết như Paint.NET hoặc Photoshop sẽ được chấp nhận. API hình ảnh nâng cao Java có vẻ hy vọng.

tôi cần nó cho một hệ thống chụp màn hình thao tác, cho phép bạn để có được hiệu ứng như:

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

Trả lời

1

dễ dàng hơn so với mô phỏng một góc độ bóp méo sử dụng xử lý ảnh, bạn có thể sử dụng OpenGL hoặc DirectX (XNA) để thực sự thực hiện hiển thị phối cảnh.

Làm cho hình tứ giác đơn giản với hình ảnh của bạn làm bản đồ kết cấu. Thiết lập cảnh của bạn, hiển thị cho bộ đệm và bạn có hình ảnh của mình.

Cập nhật Nó chỉ ra rằng XNA là một thư viện vô lý (hướng tới tạo trò chơi và không có gì khác, ngáp). DirectX được quản lý yêu cầu phải có phẫu thuật sọ não. OpenGL rất dễ sử dụng nhưng thiếu mã tải hình ảnh. Điều này khiến chúng tôi với WPF:

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

Những hình ảnh có thể được cải thiện bằng cách buộc WPF vào chế độ chống bí danh (tại sao oh lý do tại sao Microsoft là bạn rất thiển cận?), Và bằng cách không sử dụng Aero kính mà lực lượng đường viền màu đen 1 pixel trên tất cả các ảnh chụp màn hình (hoặc bằng cách xóa đường viền 1 pixel đó).

(Xin lỗi vì chiều dài của mã này, nhưng WPF là một API tán gẫu.)

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]; 
    } 
} 

Và XAML yêu cầu:

<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

Vấn đề là, làm cách nào để chuyển đổi 4 điểm thành vòng xoay 3D? –

2

Các từ khóa ở đây là homography. Manolis Lourakis đã viết một bài thực hành GPL'ed homography trong C có sẵn here; tuy nhiên, điều này sẽ không thể được chuyển dễ dàng vì nó dựa trên một số thư viện bên ngoài như LAPACK.

2

Disclaimer: Tôi làm việc tại Atalasoft

Nếu bạn sẵn sàng để đi thương mại, DotImage Ảnh có thể làm điều này với QuadrilateralWarpCommand. Mẫu C# Mã

// 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

Đây có phải là một sợi dọc hay một sợi dọc? –

+0

Tôi không tin rằng bạn có thể nhận được điều này với một warp Affine (ít nhất là không 2d) Chúng tôi hỗ trợ một số biến đổi affine phổ biến, và bạn có thể làm cho ma trận 2D của riêng bạn. Chúng tôi không hỗ trợ chuyển đổi 3D (đó là những gì tôi nghĩ rằng bạn sẽ cần phải làm loại chuyển đổi này bằng cách sử dụng một ma trận). –

Các vấn đề liên quan