Introducción:
Pues eso, que a raíz de una consulta en mis foros, me decidí a hacer el
ejemplo, y así de paso te pongo algo de manipulación de imágenes, que de
eso, yo en particular casi no escribo... creo que este es el primer artículo
que publico sobre el manejo de imágenes.
Te explico que es lo que hace el código que te voy a mostrar
En esta primera parte, he creado un formulario en el que hay control
PictureBox que será el usado para mostrar la imagen que vamos a trocear.
También hay un control GroupBox en el que hay 9 controles de tipo
PictureBox, en esos controles será donde mostremos cada uno de los trozos, y
como es de suponer, cada trozo es una parte de la imagen original, y por
tanto, si los juntamos todos, formarán esa imagen.
Este primer ejemplo, no solo permite trocear la imagen en 9 trozos (3
filas y 3 columnas), sino que puedes trocearla en menos trozos, aunque el
máximo será de 3 columnas y 3 filas.
En este otro ejemplo, puedes ver el código para trocear la imagen en el
número de filas y columnas que quieras.
El proceso para trocear es el siguiente:
- Se calcula el tamaño de cada trozo de la imagen original, para ello
se divide el ancho de la imagen original por el número de columnas y el
alto de dicha imagen por el número de filas:
' Visual Basic
Dim tamTrozoW As Integer = Me.picMain.Image.Width \ columnas
Dim tamTrozoH As Integer = Me.picMain.Image.Height \ filas
// C#
int tamTrozoW = this.picMain.Image.Width / columnas;
int tamTrozoH = this.picMain.Image.Height / filas;
- Se calcula cuanto ocupará cada imagen, en este caso, el tamaño de
uno de los 9 controles que están en el GroupBox:
' Visual Basic
' El tamaño de cada trozo
Dim nW As Integer = pic0.Width
Dim nH As Integer = pic0.Height
' El rectángulo de cada nuevo trozo
Dim rectDest As New Rectangle(0, 0, nW, nH)
// C#
// El tamaño de cada trozo
int nW = pic0.Width;
int nH = pic0.Height;
// El rectángulo que ocupará cada nuevo trozo
Rectangle rectDest = new Rectangle(0, 0, nW, nH);
- Creamos un array con los 9 controles, para que resulte más fácil
controlarlas:
' Visual Basic
Dim trozos() As PictureBox = {pic0, pic1, pic2, pic3, pic4, pic5, pic6, pic7, pic8}
// C#
PictureBox[] trozos = { pic0, pic1, pic2, pic3, pic4, pic5, pic6, pic7, pic8 };
- Usamos un bucle para obtener cada trozo, inicialmente el primer
trozo estará en la posición 0,0,
(fíjate que en C#, a diferencia de Visual Basic, hay que inicializar las
variables):
' Visual Basic
' Para contar cada columna
Dim c As Integer
' La posición X e Y en la imagen original
Dim pX, pY As Integer
For i As Integer = 0 To trozos.Length - 1
// C#
// Para contar cada columna
int c = 0;
// La posición X e Y en la imagen original
int pX = 0, pY = 0;
for (int i = 0; i < trozos.Length; i++)
- En cada repetición del bucle troceamos una imagen, y la vamos
asignando al elemento del array que corresponda. Para realizar el
recorte y asignarlo a la imagen de destino, usamos un objeto de tipo
Graphics obtenido de la imagen de destino, la imagen la dibujamos usando
el método DrawImage en el que le indicamos que trozo queremos de la
imagen original, trozo que indicamos con un objeto Rectangle (rectOrig)
al que le asignamos los valores X e Y además del ancho y alto que
anteriormente calculamos y que tenemos guardado en las variables tamTrozoW
y tamTrozoH
respectivamente. La posición en la que queremos insertar la nueva imagen
la indicamos con el rectángulo
de destino (rectDest), que siempre es el mismo, por eso esa asignación la
hacemos fuera del bucle:
' Visual Basic
' El trozo de la imagen original
rectOrig = New Rectangle(pX, pY, tamTrozoW, tamTrozoH)
' La imagen de destino
bmpDest = New Bitmap(tamTrozoW, tamTrozoW)
g = Graphics.FromImage(bmpDest)
' Obtenemos un trozo de la imagen original
' y lo dibujamos en la imagen de destino
g.DrawImage(picMain.Image, rectDest, rectOrig, GraphicsUnit.Pixel)
' Asignamos la nueva imagen al picture correspondiente
trozos(i).Image = bmpDest
// C#
// El trozo de la imagen original
rectOrig = new Rectangle(pX, pY, tamTrozoW, tamTrozoH);
// La imagen de destino
bmpDest = new Bitmap(tamTrozoW, tamTrozoW);
g = Graphics.FromImage(bmpDest);
// Obtenemos un trozo de la imagen original
// y lo dibujamos en la imagen de destino
g.DrawImage(picMain.Image, rectDest, rectOrig, GraphicsUnit.Pixel);
// Asignamos la nueva imagen al picture correspondiente
trozos[i].Image = bmpDest;
- Incrementamos el valor de la posición horizontal (pX) e
incrementamos el número de columna, si hemos llegado al número de columnas indicadas, es que estamos en
la siguiente fila, por tanto ponemos a cero el valor de la posición X e
incrementamos la posición Y (pY):
' Visual Basic
c += 1
pX += tamTrozoW
' Cuando hayamos recorrido las columnas,
' pasamos a la siguiente fila
If c >= columnas Then
c = 0
pX = 0
pY += tamTrozoH
End If
Next
// C#
c += 1;
pX += tamTrozoW;
// Cuando hayamos recorrido las columnas,
// pasamos a la siguiente fila
if (c >= columnas)
{
c = 0;
pX = 0;
pY += tamTrozoH;
}
}
Y eso es todo.
Aquí tienes una captura del formulario en tiempo de diseño y más abajo
tienes el código completo, tanto para Visual Basic .NET
como para C#.
En el caso de C#, tendrás que asociar los eventos de los controles con los
métodos mostrados, en Visual Basic no hace falta, ya que con la instrucción
Handles se asocia automáticamente.
Figura 1. El formulario en tiempo de diseño
Espero que te sea de utilidad.
Nos vemos.
Guillermo
Aquí tienes otro ejemplo,
pero usando un número dinámico de filas y columnas.
El código para Visual Basic .NET
(cualquier versión)
|
'------------------------------------------------------------------------------
' Trocear una imagen (17/Ene/07)
'
' ©Guillermo 'guille' Som, 2007
'------------------------------------------------------------------------------
Option Strict On
Imports Microsoft.VisualBasic
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1
Private Sub btnExaminar_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles btnExaminar.Click
Dim oFD As New OpenFileDialog
oFD.Title = "Seleccionar imagen"
oFD.Filter = "Imágenes|*.jpg;*.gif;*.png;*.bmp|Todos (*.*)|*.*"
oFD.FileName = Me.txtImagen.Text
If oFD.ShowDialog = Windows.Forms.DialogResult.OK Then
Me.txtImagen.Text = oFD.FileName
Me.picMain.Image = Image.FromFile(Me.txtImagen.Text)
End If
End Sub
Private Sub btnTrocear_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles btnTrocear.Click
' Trocear una imagen en trozos más pequeños
Const columnas As Integer = 3
Const filas As Integer = 3
'
' El tamaño proporcional del ancho y alto
' correspondientes a los trozos a usar
Dim tamTrozoW As Integer = Me.picMain.Image.Width \ columnas
Dim tamTrozoH As Integer = Me.picMain.Image.Height \ filas
' El tamaño de cada trozo
Dim nW As Integer = pic0.Width
Dim nH As Integer = pic0.Height
' El rectángulo de cada nuevo trozo
Dim rectDest As New Rectangle(0, 0, nW, nH)
' Estas variables se usan en el bucle
Dim bmpDest As Bitmap
Dim g As Graphics
Dim rectOrig As Rectangle
'
' Array con los pictures que hay en el formulario
Dim trozos() As PictureBox = {pic0, pic1, pic2, pic3, pic4, pic5, pic6, pic7, pic8}
' Para contar cada columna
Dim c As Integer
' La posición X e Y en la imagen original
Dim pX, pY As Integer
For i As Integer = 0 To trozos.Length - 1
' El trozo de la imagen original
rectOrig = New Rectangle(pX, pY, tamTrozoW, tamTrozoH)
' La imagen de destino
bmpDest = New Bitmap(tamTrozoW, tamTrozoW)
g = Graphics.FromImage(bmpDest)
' Obtenemos un trozo de la imagen original
' y lo dibujamos en la imagen de destino
g.DrawImage(picMain.Image, rectDest, rectOrig, GraphicsUnit.Pixel)
' Asignamos la nueva imagen al picture correspondiente
trozos(i).Image = bmpDest
c += 1
pX += tamTrozoW
' Cuando hayamos recorrido las columnas,
' pasamos a la siguiente fila
If c >= columnas Then
c = 0
pX = 0
pY += tamTrozoH
End If
Next
End Sub
End Class
|
El código para C#
(cualquier versión)
|
//-----------------------------------------------------------------------------
// Trocear una imagen (17/Ene/07)
//
// ©Guillermo 'guille' Som, 2007
//-----------------------------------------------------------------------------
using System;
using System.Windows.Forms;
using System.Drawing;
namespace trocearImagen_cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnExaminar_Click(object sender, EventArgs e)
{
OpenFileDialog oFD = new OpenFileDialog();
oFD.Title = "Seleccionar imagen";
oFD.Filter = "Imágenes|*.jpg;*.gif;*.png;*.bmp|Todos (*.*)|*.*";
oFD.FileName = this.txtImagen.Text;
if (oFD.ShowDialog() == DialogResult.OK)
{
this.txtImagen.Text = oFD.FileName;
this.picMain.Image = Image.FromFile(this.txtImagen.Text);
}
}
private void btnTrocear_Click(object sender, EventArgs e)
{
// Trocear una imagen en trozos más pequeños
const int columnas = 3;
const int filas = 3;
//
// El tamaño proporcional del ancho y alto
// correspondientes a los trozos a usar
int tamTrozoW = this.picMain.Image.Width / columnas;
int tamTrozoH = this.picMain.Image.Height / filas;
// El tamaño de cada trozo
int nW = pic0.Width;
int nH = pic0.Height;
// El rectángulo que ocupará cada nuevo trozo
Rectangle rectDest = new Rectangle(0, 0, nW, nH);
// Estas variables se usan en el bucle
Bitmap bmpDest;
Graphics g;
Rectangle rectOrig;
//
// Array con los pictures que hay en el formulario
PictureBox[] trozos = { pic0, pic1, pic2, pic3, pic4, pic5, pic6, pic7, pic8 };
// Para contar cada columna
int c = 0;
// La posición X e Y en la imagen original
int pX = 0, pY = 0;
for (int i = 0; i < trozos.Length; i++)
{
// El trozo de la imagen original
rectOrig = new Rectangle(pX, pY, tamTrozoW, tamTrozoH);
// La imagen de destino
bmpDest = new Bitmap(tamTrozoW, tamTrozoW);
g = Graphics.FromImage(bmpDest);
// Obtenemos un trozo de la imagen original
// y lo dibujamos en la imagen de destino
g.DrawImage(picMain.Image, rectDest, rectOrig, GraphicsUnit.Pixel);
// Asignamos la nueva imagen al picture correspondiente
trozos[i].Image = bmpDest;
c += 1;
pX += tamTrozoW;
// Cuando hayamos recorrido las columnas,
// pasamos a la siguiente fila
if (c >= columnas)
{
c = 0;
pX = 0;
pY += tamTrozoH;
}
}
}
}
}
|
Espacios de nombres usados en el código de este artículo:
System.Windows.Forms
System.Drawing
Compatibilidad:
Este código funciona con cualquier versión de .NET
Windows Vista ready! ;-)))
|