2010-12-09 39 views
5

Estoy buscando una forma de rotar una imagen para cortar un rectángulo dentro de esta imagen y guardarla como una imagen separada.WPF: Cortar y guardar imagen

Illustration

Editar: Ver respuesta aceptada para la solución.

Respuesta

4

actualización
leí tu pregunta de nuevo y esta es probablemente más cercano a su problema. No entendí muy bien cómo usar las coordenadas, pero este método tomará una imagen de mapa de bits, la rotará en un ángulo y guardará una versión recortada de los valores iniciales X, Y con el ancho y el alto especificados. Probablemente no sea 100% como lo que estás tratando de hacer pero con suerte puedes usar la idea.

public void RotateAndSaveImage(BitmapImage sourceImage, 
           double angle, 
           int startX, 
           int startY, 
           int width, 
           int height, 
           string filePath) 
{ 
    TransformGroup transformGroup = new TransformGroup(); 
    RotateTransform rotateTransform = new RotateTransform(angle); 
    rotateTransform.CenterX = sourceImage.PixelWidth/2.0; 
    rotateTransform.CenterY = sourceImage.PixelHeight/2.0; 
    transformGroup.Children.Add(rotateTransform); 
    TranslateTransform translateTransform = new TranslateTransform(); 
    translateTransform.X = -startX; 
    translateTransform.Y = -startY; 
    transformGroup.Children.Add(translateTransform); 

    DrawingVisual vis = new DrawingVisual(); 
    DrawingContext cont = vis.RenderOpen(); 
    cont.PushTransform(transformGroup); 
    cont.DrawImage(sourceImage, new Rect(new Size(sourceImage.PixelWidth, sourceImage.PixelHeight))); 
    cont.Close(); 

    RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default); 
    rtb.Render(vis); 

    FileStream stream = new FileStream(filePath, FileMode.Create); 
    PngBitmapEncoder encoder = new PngBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(rtb)); 
    encoder.Save(stream); 
    stream.Close(); 
} 

Gracias por su puesto, tuve que alterar la función un poco:

private static double RadianToDegree(double angle) 
    { 
     return angle * (180.0/Math.PI); 
    } 

    public static double GetDistanceBetweenPoints(Point p, Point q) 
    { 
     var a = p.X - q.X; 
     var b = p.Y - q.Y; 
     return Math.Sqrt(a * a + b * b); 
    } 

    private static double CalculateTheta(Point p1, Point p2) 
    { 
     var deltaX = Math.Abs(p1.Y - p2.Y); 
     var deltaY = Math.Abs(p1.X - p2.X); 
     var theta = RadianToDegree(Math.Atan(deltaY/deltaX)); 
     return (90 - theta) * -1; 
    } 

    public void RotateAndSaveImage(string sourceFile, List<Point> subCoords) 
    { 
     var bitmap = new BitmapImage(); 
     bitmap.BeginInit(); 
     bitmap.UriSource = new Uri(sourceFile); 
     bitmap.EndInit(); 

     var p1 = subCoords[0]; 
     var p2 = subCoords[1]; 
     var p4 = subCoords[3]; 

     var theta = CalculateTheta(p1, p2); 
     var width = GetDistanceBetweenPoints(p1, p2); 
     var height = GetDistanceBetweenPoints(p1, p4); 

     var transformGroup = new TransformGroup(); 
     var rotateTransform = new RotateTransform(theta) 
     { 
      CenterX = p1.X, 
      CenterY = p1.Y 
     }; 
     transformGroup.Children.Add(rotateTransform); 

     var translateTransform = new TranslateTransform 
     { 
      X = -p1.X, 
      Y = -p1.Y 
     }; 

     transformGroup.Children.Add(translateTransform); 

     var vis = new DrawingVisual(); 

     using (var cont = vis.RenderOpen()) 
     { 
      cont.PushTransform(transformGroup); 
      cont.DrawImage(bitmap, new Rect(
       new Size(bitmap.PixelWidth, bitmap.PixelHeight))); 
     } 

     var rtb = new RenderTargetBitmap((int)width, (int)height, 
      96d, 96d, PixelFormats.Default); 
     rtb.Render(vis); 

     using (var stream = new FileStream(TargetFile, FileMode.Create)) 
     { 
      var encoder = new JpegBitmapEncoder(); 
      encoder.Frames.Add(BitmapFrame.Create(rtb)); 
      encoder.Save(stream); 
     } 
    } 

El código anterior funciona perfectamente. Nunca lo hubiera logrado sin tu ayuda.

Cuestiones relacionadas