template Redimensionner les images transparentes en utilisant C#



xamarin forms sample (4)

Alors que le format PNG est certainement meilleur que le format GIF, il est parfois nécessaire d'utiliser le format GIF.

Avec le format GIF ou PNG 8 bits, vous devez résoudre le problème de la quantification.

La quantification est l'endroit où vous choisissez quelles 256 couleurs (ou moins) vont le mieux préserver et représenter l'image, puis retourner les valeurs RVB dans les index. Lorsque vous effectuez une opération de redimensionnement, la palette de couleurs idéale change, car vous mélangez les couleurs et modifiez les balances.

Pour les redimensionnements légers, comme 10-30%, vous pouvez bien conserver la palette de couleurs d'origine.

Cependant, dans la plupart des cas, vous devrez re-quantifier.

Les deux principaux algorithmes à choisir sont Octree et nQuant. Octree est très rapide et fait un très bon travail, surtout si vous pouvez superposer un algorithme de tramage intelligent. nQuant nécessite au moins 80 Mo de RAM pour effectuer un encodage (il construit un histogramme complet), et est généralement plus lent de 20 à 30 fois (1 à 5 secondes par encodage sur une image moyenne). Cependant, il produit parfois une qualité d'image supérieure à celle d'Octree puisqu'il ne «arrondit» pas les valeurs pour maintenir des performances constantes.

Lors de l'implémentation du GIF transparent et du support GIF animé dans le projet imageresizing.net , j'ai choisi Octree. La prise en charge de la transparence n'est pas difficile une fois que vous avez le contrôle de la palette d'images.

Quelqu'un at-il la formule secrète pour redimensionner des images transparentes (principalement des GIF) sans aucune perte de qualité - quoi de neuf?

J'ai essayé plein de trucs, le plus proche n'est pas assez bon.

Jetez un oeil à mon image principale:

http://www.thewallcompany.dk/test/main.gif

Et puis l'image mise à l'échelle:

http://www.thewallcompany.dk/test/ScaledImage.gif

//Internal resize for indexed colored images
void IndexedRezise(int xSize, int ySize)
{
  BitmapData sourceData;
  BitmapData targetData;

  AdjustSizes(ref xSize, ref ySize);

  scaledBitmap = new Bitmap(xSize, ySize, bitmap.PixelFormat);
  scaledBitmap.Palette = bitmap.Palette;
  sourceData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
    ImageLockMode.ReadOnly, bitmap.PixelFormat);
  try
  {
    targetData = scaledBitmap.LockBits(new Rectangle(0, 0, xSize, ySize),
      ImageLockMode.WriteOnly, scaledBitmap.PixelFormat);
    try
    {
      xFactor = (Double)bitmap.Width / (Double)scaledBitmap.Width;
      yFactor = (Double)bitmap.Height / (Double)scaledBitmap.Height;
      sourceStride = sourceData.Stride;
      sourceScan0 = sourceData.Scan0;
      int targetStride = targetData.Stride;
      System.IntPtr targetScan0 = targetData.Scan0;
      unsafe
      {
        byte* p = (byte*)(void*)targetScan0;
        int nOffset = targetStride - scaledBitmap.Width;
        int nWidth = scaledBitmap.Width;
        for (int y = 0; y < scaledBitmap.Height; ++y)
        {
          for (int x = 0; x < nWidth; ++x)
          {
            p[0] = GetSourceByteAt(x, y);
            ++p;
          }
          p += nOffset;
        }
      }
    }
    finally
    {
      scaledBitmap.UnlockBits(targetData);
    }
  }
  finally
  {
    bitmap.UnlockBits(sourceData);
  }
}

J'utilise le code ci-dessus, pour faire le redimensionnement indexé.

Est-ce que quelqu'un a des idées d'amélioration?


Answer #1

Pour tous ceux qui essaient d'utiliser la solution de Markus Olsson pour redimensionner dynamiquement les images et les écrire dans le flux de réponses.

Cela ne fonctionnera pas:

Response.ContentType = "image/png";
dst.Save( Response.OutputStream, ImageFormat.Png );

Mais cela va:

Response.ContentType = "image/png";
using (MemoryStream stream = new MemoryStream())
{
    dst.Save( stream, ImageFormat.Png );

    stream.WriteTo( Response.OutputStream );
}

Answer #2

C'est une fonction de redimensionnement de base que j'ai utilisée pour certaines de mes applications qui exploitent GDI +

/// <summary>
///    Resize image with GDI+ so that image is nice and clear with required size.
/// </summary>
/// <param name="SourceImage">Image to resize</param>
/// <param name="NewHeight">New height to resize to.</param>
/// <param name="NewWidth">New width to resize to.</param>
/// <returns>Image object resized to new dimensions.</returns>
/// <remarks></remarks>
public static Image ImageResize(Image SourceImage, Int32 NewHeight, Int32 NewWidth)
{
   System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(NewWidth, NewHeight, SourceImage.PixelFormat);

   if (bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Format1bppIndexed | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Format4bppIndexed | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Format8bppIndexed | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Undefined | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.DontCare | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Format16bppArgb1555 | bitmap.PixelFormat == Drawing.Imaging.PixelFormat.Format16bppGrayScale) 
   {
      throw new NotSupportedException("Pixel format of the image is not supported.");
   }

   System.Drawing.Graphics graphicsImage = System.Drawing.Graphics.FromImage(bitmap);

   graphicsImage.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality;
   graphicsImage.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
   graphicsImage.DrawImage(SourceImage, 0, 0, bitmap.Width, bitmap.Height);
   graphicsImage.Dispose();
   return bitmap; 
}

Je ne me souviens pas du tout si cela fonctionnera avec les GIF, mais vous pouvez essayer.

Note: Je ne peux pas prendre le crédit complet pour cette fonction. J'ai reconstitué quelques éléments à partir d'autres échantillons en ligne et l'ai fait fonctionner selon mes besoins. 8 ^ D


Answer #3

Je pense que le problème est que vous effectuez un redimensionnement basé sur la ligne d'analyse, ce qui va conduire à des crénelures, peu importe à quel point vous le modifiez. Une bonne qualité de redimensionnement de l'image vous oblige à faire un peu plus de travail pour déterminer la couleur moyenne des pixels pré-redimensionnés que couvre votre pixel redimensionné.

Le gars qui dirige ce site Web a un billet de blog qui traite de quelques algorithmes de redimensionnement d'image. Vous voulez probablement un algorithme d'échelle d'image bicubique.

Meilleur redimensionnement de l'image





image-scaling