5 votes

Redimensionner l'image et la placer dans un tableau d'octets pour CrystalReports BlobField

J'ai essayé de faire des recherches à ce sujet et j'ai un code qui devrait fonctionner d'après ce que je vois, mais l'image résultante dans mon rapport Crystal est de 5 pages au lieu d'une pour une raison ou une autre !

J'ai un rapport Crystal avec une image pleine page provenant d'un BlobField qui fonctionne parfaitement lorsque l'image source fait 2409 pixels de large et 3436 pixels de haut à 300 dpi.

Lorsque j'essaie d'utiliser une image source de 1700 de large par 2436 de haut à 200 dpi, la hauteur de l'image est trop grande et dépasse un peu le rapport sur la page suivante.

Je me suis dit "pas de problème, je vais juste redimensionner l'image et le rapport s'affichera correctement", mais j'ai de grandes difficultés à le faire Voici le code que j'utilise en ce moment - lorsque j'utilise la taille "normale" de l'image et ce code, tout s'affiche correctement dans le rapport, mais si j'ai besoin de redimensionner, l'image s'étire massivement en largeur et sur CINQ pages, ce qui est encore pire que de la laisser telle quelle ! :(

Dim fs As System.IO.FileStream = New System.IO.FileStream(FilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim Image() As Byte = New Byte(fs.Length - 1) {}
fs.Read(Image, 0, CType(fs.Length, Integer))
fs.Close()

'Byte[] to image
Dim imgMemoryStream = New IO.MemoryStream(Image)
Dim myImage = Drawing.Image.FromStream(imgMemoryStream)

' Check if image is 2409 wide, if it's not then resize to 2409 while preserving aspect ratio. WIN.
If myImage.Width <> 2409 Then
    MsgBox("myimage before: " & myImage.Width & " by " & myImage.Height)
    myImage = ImageResize(myImage, 3436, 2409)
    MsgBox("myimage after: " & myImage.Width & " by " & myImage.Height)
Else
    MsgBox("myimage (already correct for printing): " & myImage.Width & " by " & myImage.Height)
End If

Dim imgMemoryStream2 As IO.MemoryStream = New IO.MemoryStream()
myImage.Save(imgMemoryStream2, System.Drawing.Imaging.ImageFormat.Jpeg)
Image = imgMemoryStream2.ToArray

objDataRow(strImageField) = Image

Je récupère donc l'image originale dans un tableau d'octets (car je suppose que la taille de l'image est "normale" par défaut et je l'insère directement dans le champ Blob), puis je la reconvertis en image pour vérifier la taille de l'image. Si la taille n'est pas "normale", je redimensionne l'image puis je la reconvertis en tableau d'octets pour l'insérer dans le champ BlobField du rapport.

Il s'agit du code de redimensionnement de l'image :

Public Shared Function ImageResize(ByVal image As System.Drawing.Image, _
ByVal height As Int32, ByVal width As Int32) As System.Drawing.Image
Dim bitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(width, height, image.PixelFormat)
If bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Format1bppIndexed Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Format4bppIndexed Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Format8bppIndexed Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Undefined Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.DontCare Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Format16bppArgb1555 Or _
bitmap.PixelFormat = Drawing.Imaging.PixelFormat.Format16bppGrayScale Then
Throw New NotSupportedException("Pixel format of the image is not supported.")
End If
Dim graphicsImage As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bitmap)
graphicsImage.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
graphicsImage.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
graphicsImage.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height)
graphicsImage.Dispose()
Return bitmap
End Function

Peut-être que je n'aborde pas le problème de la bonne manière, mais j'essaie de trouver un moyen de permettre aux images de toutes tailles d'être déposées dans le champ Blob de Crystal Reports et d'occuper une page A4 complète.

0voto

Dave Lucre Points 412

Vous devriez avoir déjà stocké votre image (sous forme de byte[]) quelque part, et la passer à cette fonction ResizeBytes, avec les nouvelles dimensions que vous souhaitez donner à l'image renvoyée.

private byte[] ResizeBytes(byte[] byteImageIn, int NewWidth, int NewHeight)
{
    //Convert Bytes to Image
    MemoryStream ms1 = new MemoryStream(byteImageIn);
    Image img = Image.FromStream(ms1);

    //Convert Image in to new image with new dimensions, padding with a white background
    img = FixedSize(img, NewWidth, NewHeight);

    //Convert image back to a byte array
    MemoryStream ms2 = new MemoryStream();
    img.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
    byte[] imageBytes = ms2.ToArray();
    return imageBytes;
}

La fonction FixedSize :

private Image FixedSize(Image imgPhoto, int Width, int Height)
{
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0;

    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;

    nPercentW = ((float)Width / (float)sourceWidth);
    nPercentH = ((float)Height / (float)sourceHeight);
    if (nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((Width -
                      (sourceWidth * nPercent)) / 2);
    }
    else
    {
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((Height -
                      (sourceHeight * nPercent)) / 2);
    }

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);

    Bitmap bmPhoto = new Bitmap(Width, Height,
                      PixelFormat.Format48bppRgb); //Format24bppRgb
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                     imgPhoto.VerticalResolution);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.White);
    grPhoto.InterpolationMode =
            InterpolationMode.HighQualityBicubic;

    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();
    return bmPhoto;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X