Muy buenas. Llevo varios días dale que te pego, y nada
. Me explico:
Estoy tratando de generar con Crystal Reports (el que viene en VS.Net 2003) un carnet de cliente. La foto del cliente tiene que ir en un marco que mide como máximo 1290 twips de ancho por 1600 twips de alto (20 twips = 1/72'' = 1 punto <> 1 pixel). Las imágenes están digitalizadas generalmente a 300 ppp (dpi) pero son cada una de un tamaño diferente. La idea es encuadrar esta imagen, comprobando primero cuál de las dimensiones es la que hay que marcar como, digamos, variable independiente. Para ello, dividiendo al alto entre el ancho del marco de Crystal Reports es obtiene una proporción. Haciendo lo mismo con la imagen (aunque tengamos las medidas en píxeles) sacamos otra proporción. Comparando ambas proporciones podremos saber si tenemos que fijar la anchura o la altura de la imagen.
El problema me surge a la hora de, una vez definida cuál es la dimensión a fijar, redimensionar la imagen en píxeles al marco en twips. Os dejo el código que he modificado por activa y por pasiva sin obtener buenos resultados. Entiendo que habría que tener en cuenta la resolución
de la imagen al hacer el paso de píxeles a twips.
Código:
Private Sub imgbCarne_Click(ByVal sender As System.Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles imgbCarne.Click
Try
Dim rpt As New CrystalDecisions.CrystalReports.Engine.ReportDocument
Dim dt As New DataTable("datos")
Dim dr As DataRow
Dim ds As New DataSet
Try
rpt.Load(Server.MapPath("../Reportes/CarneCliente.rpt"), CrystalDecisions.[Shared].OpenReportMethod.OpenReportByTempCopy)
Catch ex As Exception
mens("No se ha podido cargar el reporte<br>" & ex.Message)
Exit Sub
End Try
Dim img As Drawing.Image = Image.FromFile("\\192.168.0.31\FotosClientes\" & Me.lblNumCliente.Text.Trim & ".JPG")
Dim redImg As Drawing.Image
Dim byteImg() As Byte
Dim maxAncho As Single = 1290
Dim maxAlto As Single = 1600
Dim maxProp As Double = maxAlto / maxAncho
Dim ancho As Double = img.Width
Dim alto As Double = img.Width
Dim prop As Double = alto / ancho
If prop / maxProp < 1 Then
'Limitante la altura
alto = CInt(maxAlto)
'alto = maxAlto * img.VerticalResolution / 1440
ancho = 0
'tam = New Drawing.Size((maxAlto * img.VerticalResolution / 1440) / maxProp, maxAlto * img.VerticalResolution / 1440)
'nImg = New Bitmap(img, tam)
Else
'Limitante la anchura
ancho = CInt(maxAncho)
'ancho = maxAncho * img.HorizontalResolution / 1440
alto = 0
'tam = New Drawing.Size(maxAncho * img.HorizontalResolution / 1440, maxProp * maxAncho * img.VerticalResolution / 1440)
'nImg = New Bitmap(img, tam)
End If
Try
redImg = RedimensionarImagen(img, ancho, alto)
'redImg.Save("\\192.168.0.31\FotosClientes\BMP___" & Me.lblNumCliente.Text.Trim & ".JPG", Drawing.Imaging.ImageFormat.Jpeg)
'Exit Sub
byteImg = ImageToByte(redImg)
Catch ex As Exception
mens("Error al redimensionar la imagen original.<br>" & ex.Message)
Exit Sub
End Try
dt.Columns.Add(New DataColumn("NumCliente", GetType(Short)))
dt.Columns.Add(New DataColumn("Nombre", GetType(String)))
dt.Columns.Add(New DataColumn("Apellidos", GetType(String)))
dt.Columns.Add(New DataColumn("DNI", GetType(String)))
dt.Columns.Add(New DataColumn("Fecha", GetType(String)))
dt.Columns.Add(New DataColumn("Imagen", GetType(Byte())))
dr = dt.NewRow()
dr("NumCliente") = Me.lblNumCliente.Text.ToUpper
dr("Nombre") = Me.txtNombre.Text.Trim.ToUpper
dr("Apellidos") = Me.txtApellido1.Text.Trim.ToUpper & " " & Me.txtApellido2.Text.Trim.ToUpper
dr("DNI") = Me.txtNIF.Text.Trim.ToUpper
dr("Fecha") = Me.txtFechaAlta.Text
dr("Imagen") = byteImg
dt.Rows.Add(dr)
ds.Tables.Add(dt)
rpt.SetDataSource(ds)
'rpt.PrintOptions.PrinterName = "\\BRAVENAP\Smart Driver"
'rpt.PrintOptions.PaperSize = CrystalDecisions.[Shared].PaperSize.DefaultPaperSize
Try
rpt.ReportDefinition.Sections("Section3").ReportObjects("Foto").Width = redImg.Width
rpt.ReportDefinition.Sections("Section3").ReportObjects("Foto").Height = redImg.Height
Catch ex As Exception
mens("Error al dimensionar la imagen en el reporte." & ex.message)
Exit Sub
End Try
rpt.Refresh()
Dim rptStream As New IO.MemoryStream
Try
rptStream = rpt.ExportToStream(CrystalDecisions.[Shared].ExportFormatType.WordForWindows)
Catch ex As Exception
mens("No se ha podido exportar el reporte<br>" & ex.Message)
Exit Sub
Catch ex As CrystalDecisions.CrystalReports.Engine.EngineException
mens("EngineException: No se ha podido exportar el reporte<br>" & ex.Message)
Exit Sub
Catch ex As CrystalDecisions.CrystalReports.Engine.ExportException
mens("ExportException: No se ha podido exportar el reporte<br>" & ex.Message)
Exit Sub
End Try
Response.Clear()
Response.Buffer = True
Response.ContentType = "application/msword"
Response.AddHeader("Content-Disposition", "attachment;filename=" & "CarneCliente" & Me.txtNumCliente.Text & ".doc")
Response.BinaryWrite(rptStream.ToArray())
Response.End()
Catch ex As Exception
mens("Error genérico: " & ex.Message)
End Try
End Sub
Private Function RedimensionarImagen(ByVal imagen As Drawing.Image, ByVal ancho As Integer, ByVal alto As Integer) As Drawing.Image
' throw an exception if both arguments are not positive integers
If ancho <= 0 AndAlso alto <= 0 Then
Throw New Exception("Ancho y/o alto deben tener argumentos positivos")
End If
Dim img As Drawing.Image = imagen
' Mantiene la proporción
If ancho <= 0 OrElse alto <= 0 Then
If ancho <= 0 Then
ancho = img.Width / (img.Height / alto)
ElseIf alto <= 0 Then
alto = img.Height / (img.Width / ancho)
End If
End If
' Nuevo mapa de bits con el tamaño especificado
Dim bmp As New System.Drawing.Bitmap(ancho, alto)
' Lienzo para rellenar el mapa de bits
Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage( _
DirectCast(bmp, System.Drawing.Image))
' Copia la imagen original sobre el lienzo
g.DrawImage(img, 0, 0, ancho, alto)
' Cierra la imagen original
img.Dispose()
' Guarda la nueva imagen con el formato correcto
Dim stream As New IO.MemoryStream
Try
bmp.Save(stream, Drawing.Imaging.ImageFormat.Jpeg)
Catch ex As Exception
Throw New Exception("Error al convertir la nueva imagen.<br>" & ex.Message)
End Try
bmp.Dispose()
Return Drawing.Image.FromStream(stream)
End Function
Llevo varias días liado con esto y no lo consigo a lo que hay que añadir que al usar una impresora de tarjetas debría salir el reporte con este tamaño y el de un A4. Pero vamos, esto es menos problema.
Gracias y un saludo.