2010-07-26 10 views
4

Je charge une image JPG d'un disque dur dans un octet []. Y at-il un moyen de redimensionner l'image (réduire la résolution) sans avoir besoin de le mettre dans un objet Bitmap?Manipulation d'images en C#

grâce

+5

Pourquoi serait en utilisant 'Bitmap' ne pas être approprié? –

+2

Clarification: Est-ce que vous croyez que 'Bitmap' utilisera plus de mémoire qu'une image JPEG? Vous devez considérer que le redimensionnement n'est possible que si l'image entière a été décompressée dans un format bitmap. –

+0

Je préfère éviter bitmap parce qu'une fois que vous convertissez en bitmap la taille de fichier augmentera considérablement. Et si vous compressez en jpg, on perdra quelques informations de l'image – mouthpiec

Répondre

3

Il y a toujours des façons, mais si elles sont mieux ... JPG est un format d'image compressé ce qui signifie que, pour faire toute manipulation d'image, il vous faut quelque chose d'interpréter ces données. L'objet bimap va le faire pour vous mais si vous voulez aller sur une autre route, vous devrez vous pencher sur la compréhension de la spécification jpeg, créer une sorte d'analyseur, etc. Il se peut qu'il y ait des raccourcis qui peuvent être utilisés sans avoir besoin de faire une pleine interprétation du jpg original mais je pense que ce serait une mauvaise idée.

Oh, et ne pas oublier qu'il existe différents formats de fichiers JPG apparemment (JFIF et EXIF) que vous ened comprendre ...

Je pense très dur avant d'éviter les objets qui sont spécifiquement conçus pour le genre de chose que vous essayez de faire.

+2

EXIF ​​n'est pas un format jpeg. EXIF est une méta-donnée ajoutée à n'importe quel format d'image. Voir http://en.wikipedia.org/wiki/Exchangeable_image_file_format –

+0

@Philip Smith: Jamais dit que c'était un format jpeg, juste que c'était un format de fichier. Si vous chargez le fichier jpg à partir du disque, vous devez toujours savoir comment le fichier est structuré afin que vous puissiez obtenir les données d'image et les méta-données et tout le reste. – Chris

1

Un fichier .jpeg est juste un sac d'octets sans décodeur JPEG. Il y en a un intégré dans la classe Bitmap, il fait un excellent travail de décodage des fichiers .jpeg. Le résultat est un objet Bitmap, vous ne pouvez pas contourner cela.

Et il supporte le redimensionnement à travers la classe Graphics ainsi que le constructeur Bitmap (Image, Size). Mais oui, faire une image .jpeg plus petite produit souvent un fichier plus grand. C'est un effet secondaire inévitable du mode Graphics.Interpolation. Il essaie d'améliorer l'apparence de l'image réduite en exécutant les pixels à travers un filtre. Le filtre bicubique fait un excellent travail.

L'apparence de l'encodeur JPEG est excellente. Le filtre produit des couleurs de pixels interpolées, conçues pour éviter que les détails de l'image disparaissent complètement lorsque la taille est réduite. Ces valeurs de pixels mélangés rendent cependant plus difficile sur l'encodeur pour compresser l'image, produisant ainsi un fichier plus volumineux.

Vous pouvez bricoler avec Graphics.InterpolationMode et sélectionner un filtre de qualité inférieure. Produit une image plus pauvre, mais plus facile à compresser. Je doute que vous apprécierez le résultat si.

1

Voici ce que je fais. Et non, je ne pense pas que vous pouvez redimensionner une image sans la traiter d'abord en mémoire (c'est-à-dire dans un bitmap quelconque).

Un redimensionnement de qualité décent implique l'utilisation d'un algorithme d'interpolation/extrapolation; il ne peut pas seulement être "sélectionner tous les n pixels", à moins que vous ne puissiez vous contenter du plus proche voisin.

Voici quelques explications: http://www.cambridgeincolour.com/tutorials/image-interpolation.htm

protected virtual byte[] Resize(byte[] data, int width, int height) { 
var inStream = new MemoryStream(data); 
var outStream = new MemoryStream(); 

var bmp = System.Drawing.Bitmap.FromStream(inStream); 
var th = bmp.GetThumbnailImage(width, height, null, IntPtr.Zero); 
th.Save(outStream, System.Drawing.Imaging.ImageFormat.Jpeg); 
return outStream.ToArray(); }