es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

WPF: Cómo copiar una parte de un lienzo en una imagen y sobrescribir el archivo de imagen Para realizar esta tarea en WPF, puedes seguir los siguientes pasos: 1. Primero, necesitarás una referencia a la “System.Windows.Media.Imaging” para poder utilizar las clases necesarias para trabajar con imágenes. 2. Crea un objeto de la clase “RenderTargetBitmap” para capturar una representación de tu lienzo (canvas): “` csharp RenderTargetBitmap renderBitmap = new RenderTargetBitmap( (int)canvas.ActualWidth, (int)canvas.ActualHeight, 96d, 96d, PixelFormats.Default); “` 3. Luego, utilizar el método “Render” del objeto “renderBitmap” para generar una representación visual del lienzo: “` csharp renderBitmap.Render(canvas); “` 4. A continuación, crea un objeto de la clase “PngBitmapEncoder” para poder codificar la imagen capturada en el formato PNG (o puedes utilizar cualquier otro formato admitido según tus necesidades): “` csharp PngBitmapEncoder encoder = new PngBitmapEncoder(); “` 5. Agrega la imagen representada por “renderBitmap” al objeto “encoder”: “` csharp encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); “` 6. Por último, puedes guardar la imagen codificada en el archivo especificado utilizando el método “Save” del objeto “encoder”: “` csharp using (var fileStream = new FileStream(“ruta/del/archivo/imagen.png”, FileMode.Create)) { encoder.Save(fileStream); } “` Recuerda reemplazar “ruta/del/archivo/imagen.png” con la dirección donde deseas guardar la imagen o el nombre del archivo. Con estos pasos, podrás copiar una porción de un lienzo en una imagen y sobrescribir el archivo de imagen en WPF.

Lo que estoy intentando hacer:

  1. Cargar imágenes de una serie de archivos .png guardados en disco (si el archivo no existe, crear una nueva imagen y llenarla con un color dado)
  2. Agregar estas imágenes a un lienzo (tienen el mismo tamaño que el lienzo y se espera que estén principalmente fuera de la pantalla con una parte superpuesta al área real del lienzo)
  3. Dibujar en el lienzo utilizando líneas, elipses, etc.
  4. (Al guardar) tomar el lienzo y convertirlo en una imagen plana almacenada en la memoria (llamémosla CanvasImage)
  5. Para cada imagen cargada en el paso 1, calcular la parte que se superpone al área real del lienzo y copiar esa parte de CanvasImage en la parte correspondiente de la imagen original
  6. Guardar las imágenes resultantes en disco, sobrescribiendo los archivos existentes

He logrado que diferentes partes de esto funcionen en diferentes momentos, utilizando código que encontré buscando cómo hacer cada paso exacto, pero nunca el proceso completo. Estoy teniendo dificultades principalmente con los pasos 4 a 6, ya que realmente no entiendo todas las clases relacionadas con imágenes, cómo convertir entre ellas y cuál usar en cada paso del proceso. También tengo algunos problemas con el paso 1, ya que necesito poder sobrescribir los archivos al final.

He leído muchas de las preguntas relacionadas (sobrescribir imágenes, convertir un lienzo en una imagen, copiar una parte de una imagen, etc.) y he probado las soluciones (algunas de las cuales funcionaron en ejemplos más simples), pero estoy luchando para juntarlo todo.

Cualquier ayuda o consejo sería muy apreciado. Si hay algo en lo que quisieras que me extendiera, estaré encantado de hacerlo, y si quieres ver algo del código, puedo compartirlo (he probado muchas cosas diferentes, así que no estoy seguro de cuán útil sería).

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución:

    Cargar imágenes

    Para cargar imágenes desde archivos .png, puedes utilizar la clase BitmapImage proporcionada por el marco de trabajo .NET. La clase BitmapImage se puede utilizar para cargar imágenes desde diferentes fuentes, incluyendo archivos. Aquí tienes un fragmento de código para cargar imágenes desde archivos:

    // Carga todas las imágenes desde archivos y añádelas a un diccionario
    Dictionary<string, bitmapimage=""> imágenes = new Dictionary<string, bitmapimage="">();
    foreach (var archivo in Directory.EnumerateFiles("ruta_a_carpeta", "*.png"))
    {
        var mapaBits = new BitmapImage(new Uri(archivo));
        imágenes.Add(Path.GetFileNameWithoutExtension(archivo), mapaBits);
    }
    

    Este código carga todos los archivos .png de una carpeta y crea un diccionario con el nombre de cada archivo (sin la extensión) como clave y la instancia de BitmapImage como valor.

    Añadir imágenes al Canvas

    Para añadir imágenes a un Canvas, puedes crear un elemento Image con la propiedad Source establecida en la instancia de BitmapImage:

    foreach (var mapaBits in imágenes.Values)
    {
        var img = new Image
        {
            Source = mapaBits,
            Width = canvas.Width,
            Height = canvas.Height,
        };
        canvas.Children.Add(img);
    }
    

    Este código crea un elemento Image para cada instancia de BitmapImage en el diccionario y lo añade al Canvas. Las propiedades Width y Height del elemento Image se establecen en el ancho y alto del Canvas.

    Dibujar en el Canvas

    Para dibujar líneas, elipses y otras formas en el Canvas, puedes utilizar la clase DrawingContext proporcionada por el Canvas. Aquí tienes un ejemplo de cómo dibujar una línea en el Canvas:

    using (var contexto = canvas.Open())
    {
        // dibuja una línea desde (10, 10) hasta (100, 100)
        var pluma = new Pen(Brushes.Black, 2.0);
        contexto.DrawLine(pluma, new Point(10, 10), new Point(100, 100));
    }
    

    Este código abre el DrawingContext del Canvas y dibuja una línea desde (10, 10) hasta (100, 100) con un color negro y un grosor de 2.

    Convertir el Canvas a una imagen

    Para convertir el Canvas a una imagen, puedes utilizar la clase RenderTargetBitmap proporcionada por el marco de trabajo .NET. Aquí tienes un ejemplo de cómo crear una instancia de RenderTargetBitmap a partir de un Canvas:

    var mapaBits = new RenderTargetBitmap((int)canvas.Width, (int)canvas.Height, 96, 96, PixelFormats.Pbgra32);
    mapaBits.Render(canvas);
    

    Este código crea una nueva instancia de RenderTargetBitmap con el mismo tamaño que el Canvas y renderiza el Canvas en él.

    Copiar porciones del Canvas a imágenes

    Para copiar las porciones del Canvas que se superponen con las imágenes originales, puedes utilizar la clase CroppedBitmap proporcionada por el marco de trabajo .NET. Aquí tienes un ejemplo de cómo copiar la porción superpuesta del Canvas a las imágenes originales:

    foreach (var kvp in imágenes)
    {
        var nombreArchivo = kvp.Key;
        var mapaBits = kvp.Value;
        var rectángulo = new Int32Rect(0, 0, (int)canvas.Width, (int)canvas.Height);
        if (superposiciónDeImagen)
        {
            // calcula la porción superpuesta del Canvas e Imagen
            // suponiendo que imgPosition es la posición de la Imagen en el Canvas
            rectángulo = new Int32Rect(Math.Max(0, imgPosition.X),
                                       Math.Max(0, imgPosition.Y),
                                       Math.Max(0, Math.Min(mapaBits.PixelWidth, canvas.Width - imgPosition.X)),
                                       Math.Max(0, Math.Min(mapaBits.PixelHeight, canvas.Height - imgPosition.Y)));
        }
        var recortada = new CroppedBitmap(mapaBits, rectángulo);
        var codificador = new PngBitmapEncoder();
        codificador.Frames.Add(BitmapFrame.Create(recortada));
        using (var flujo = File.Create(nombreArchivo))
        {
            codificador.Save(flujo);
        }
    }
    

    Este código recorre el diccionario de imágenes, calcula la porción superpuesta del Canvas y la imagen si es necesario, crea una instancia de CroppedBitmap a partir de la porción del Canvas que se superpone con la imagen, guarda la instancia de CroppedBitmap en un archivo y sobrescribe el archivo de imagen original.

    ¡Espero que esto te ayude! Avísame si necesitas más ayuda o aclaraciones.</string,></string,>

Comments are closed.