⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmapmanipulator.cs

📁 图像管理源码
💻 CS
📖 第 1 页 / 共 3 页
字号:
/// <summary>BitmapManipulator class, provides some useful static functions which
/// operate on .NET <code>Bitmap</code> objects in useful ways.
/// 
/// Some of the useful features of this class incldue:
/// <ul>
///   <li><code>GetBitmapFromUri</code> which downloads a bitmap from a URL, providing
///   some useful error message elaboration logic to present users with a more meaningful
///   error message in the event of a failure.</li>
/// 
///   <li><code>ConvertBitmap</code> functions, which convert a bitmap from one format
///   to another, including optional quality and compression parameters for codecs like JPEG and
///   TIFF, respectively.</li>
/// 
///   <li><code>ScaleBitmap</code> and <code>ResizeBitmap</code>, for modifying the dimensions
///   of a bitmap (these are standard issue and boring, but nonetheless useful)</li>
/// 
///   <li><code>ThumbnailBitmap</code>, a very useful function that produces a thumbnail of an image
///   that fits within a given rectangle</li>
/// 
///   <li><code>OverlayBitmap</code>, a useful function that overlays one bitmap atop another
///   with a caller-defined alpha parameter.  Great for putting watermarks or logos on pictures.</li>
/// 
///   <li>A few other standard-issue image manipulation functions</li>
/// </ul>
/// 
/// NOTE: This code includes support for GIF en/decoding, via the .NET Framework's
/// System.Drawing classes.  However, in order to provide GIF functionality in your
/// application, you must license the LZW encoding scheme used in GIF files from Unisys.
/// As this is an opportunistic money-grab akin to SCO's, you are well advised to refuse
/// to do this, and instead favor PNG whenever possible.
/// 
/// For more information, see http://www.microsoft.com/DEVONLY/Unisys.htm
/// 
/// Current Version: 1.0.0
/// Revision History:
/// 1.0.0 - ajn - 9/1/2003 - First release
/// 
/// Copyright(C) 2003 Adam J. Nelson.
/// 
/// This code is hereby released for unlimited non-commercial and commercial use
/// 
/// The author makes no guarantee regarding the fitness of this code, and hereby disclaims
/// all liability for any damage incurred as a result of using this code.
/// </summary>
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;

namespace apocryph.BitmapManip
{
	/// <summary>
	/// Utility class with static methods that do various useful things
	/// with bitmaps that require multiple GDI+ calls with .NET CLR
	/// </summary>
	public class BitmapManipulator {
		//MIME types for the various image formats
		private const String MIME_JPEG = "image/jpeg";
		private const String MIME_PJPEG = "image/pjpeg";
		private const String MIME_GIF = "image/gif";
		private const String MIME_BMP = "image/bmp";
		private const String MIME_TIFF = "image/tiff";
		private const String MIME_PNG = "image/x-png";

		public class BitmapManipException : Exception {
			public BitmapManipException(String msg, Exception innerException) : base(msg, innerException) {
			}
		}

		public enum ImageCornerEnum {
			TopLeft,
			TopRight,
			BottomRight,
			BottomLeft,
			Center
		};

		public enum TiffCompressionEnum {
			CCITT3,
			CCITT4,
			LZW,
			RLE,
			None,
			Unspecified
		};

		public static String[] supportedMimeTypes = new String[] {                                                              
			MIME_GIF,                                                                  
				MIME_JPEG,
				MIME_PJPEG,
				MIME_TIFF,
				MIME_PNG,
				MIME_BMP
		};

		/// <summary>Attempts to download a bitmap from a given URI, then loads the bitmap into
		/// a <code>Bitmap</code> object and returns.
		/// 
		/// Obviously there are numerous failure cases for a function like this.  For ease 
		/// of use, all errors will be reported in a catch-all <code>BitmapManipException</code>,
		/// which provides a textual error message based on the exception that occurs.  As usual,
		/// the underlying exception is available in <code>InnerException</code> property.
		/// 
		/// Times out after 10 seconds waiting for a response from the server.</summary>
		/// 
		/// <param name="uri">String containing URI from which to retrieve image</param>
		/// 
		/// <returns>Bitmap object from URI.  Shouldn't ever be null, as any error will be reported
		///     in an exception.</returns>
		public static Bitmap GetBitmapFromUri(String uri) {
			//Convert String to URI
			try {
				Uri uriObj = new Uri(uri);

				return GetBitmapFromUri(uriObj);
			} catch (ArgumentNullException ex) {
				throw new BitmapManipException("Parameter 'uri' is null", ex);
			} catch (UriFormatException ex) {
				throw new BitmapManipException(String.Format("Parameter 'uri' is malformed: {0}", ex.Message),
											   ex);
			}
		}
		/// <summary>Attempts to download a bitmap from a given URI, then loads the bitmap into
		/// a <code>Bitmap</code> object and returns.
		/// 
		/// Obviously there are numerous failure cases for a function like this.  For ease
		/// of use, all errors will be reported in a catch-all <code>BitmapManipException</code>,
		/// which provides a textual error message based on the exception that occurs.  As usual,
		/// the underlying exception is available in <code>InnerException</code> property.
		/// 
		/// Times out after 10 seconds waiting for a response from the server.</summary>
		/// 
		/// <param name="uri"><code>Uri</code> object specifying the URI from which to retrieve image</param>
		/// 
		/// <returns>Bitmap object from URI.  Shouldn't ever be null, as any error will be reported
		///     in an exception.</returns>
		public static Bitmap GetBitmapFromUri(Uri uri) {
			return GetBitmapFromUri(uri, 10*1000);
		}

		/// <summary>Attempts to download a bitmap from a given URI, then loads the bitmap into
		/// a <code>Bitmap</code> object and returns.
		/// 
		/// Obviously there are numerous failure cases for a function like this.  For ease 
		/// of use, all errors will be reported in a catch-all <code>BitmapManipException</code>,
		/// which provides a textual error message based on the exception that occurs.  As usual,
		/// the underlying exception is available in <code>InnerException</code> property.
		/// </summary>
		/// 
		/// <param name="uri">String containing URI from which to retrieve image</param>
		/// <param name="timeoutMs">Timeout (in milliseconds) to wait for response</param>
		/// 
		/// <returns>Bitmap object from URI.  Shouldn't ever be null, as any error will be reported
		///     in an exception.</returns>
		public static Bitmap GetBitmapFromUri(String uri, int timeoutMs) {
			//Convert String to URI
			try {
				Uri uriObj = new Uri(uri);

				return GetBitmapFromUri(uriObj, timeoutMs);
			} catch (ArgumentNullException ex) {
				throw new BitmapManipException("Parameter 'uri' is null", ex);
			} catch (UriFormatException ex) {
				throw new BitmapManipException(String.Format("Parameter 'uri' is malformed: {0}", ex.Message),
											   ex);
			}
		}

		/// <summary>Attempts to download a bitmap from a given URI, then loads the bitmap into
		/// a <code>Bitmap</code> object and returns.
		/// 
		/// Obviously there are numerous failure cases for a function like this.  For ease
		/// of use, all errors will be reported in a catch-all <code>BitmapManipException</code>,
		/// which provides a textual error message based on the exception that occurs.  As usual,
		/// the underlying exception is available in <code>InnerException</code> property.
		/// </summary>
		/// 
		/// <param name="uri"><code>Uri</code> object specifying the URI from which to retrieve image</param>
		/// <param name="timeoutMs">Timeout (in milliseconds) to wait for response</param>
		/// 
		/// <returns>Bitmap object from URI.  Shouldn't ever be null, as any error will be reported
		///     in an exception.</returns>
		public static Bitmap GetBitmapFromUri(Uri uri, int timeoutMs) {
			Bitmap downloadedImage = null;

			//Create a web request object for the URI, retrieve the contents,
			//then feed the results into a new Bitmap object.  Note that we 
			//are particularly sensitive to timeouts, since this all must happen
			//while the user waits
			try {
				WebRequest req = WebRequest.Create(uri);
				req.Timeout = timeoutMs;

				//The GetResponse call actually makes the request
				WebResponse resp = req.GetResponse();

				//Check the content type of the response to make sure it is
				//one of the formats we support
				if (Array.IndexOf(BitmapManipulator.supportedMimeTypes, 
								  resp.ContentType) == -1) {
					String contentType = resp.ContentType;
					resp.Close();
					throw new BitmapManipException(String.Format("The image at the URL you provided is in an unsupported format ({0}).  Uploaded images must be in either JPEG, GIF, BMP, TIFF, PNG, or WMF formats.",
																 contentType),
												   new NotSupportedException(String.Format("MIME type '{0}' is not a recognized image type", contentType)));
				}

				//Otherwise, looks fine
				downloadedImage = new Bitmap(resp.GetResponseStream());

				resp.Close();

				return downloadedImage;
			} catch (UriFormatException exp) {
				throw new BitmapManipException("The URL you entered is not valid.  Please enter a valid URL, of the form http://servername.com/folder/image.gif",
											   exp);
			} catch (WebException exp) {
				//Some sort of problem w/ the web request
				String errorDescription;

				if (exp.Status == WebExceptionStatus.ConnectFailure) {
					errorDescription = "Connect failure";
				} else if (exp.Status == WebExceptionStatus.ConnectionClosed) {
					errorDescription = "Connection closed prematurely";
				} else if (exp.Status == WebExceptionStatus.KeepAliveFailure) {
					errorDescription = "Connection closed in spite of keep-alives";
				} else if (exp.Status == WebExceptionStatus.NameResolutionFailure) {
					errorDescription = "Unable to resolve server name.  Double-check the URL for errors";
				} else if (exp.Status == WebExceptionStatus.ProtocolError) {
					errorDescription = "Protocol-level error.  The server may have reported an error like 404 (file not found) or 403 (access denied), or some other similar error";
				} else if (exp.Status == WebExceptionStatus.ReceiveFailure) {
					errorDescription = "The server did not send a complete response";
				} else if (exp.Status == WebExceptionStatus.SendFailure) {
					errorDescription = "The complete request could not be sent to the server";
				} else if (exp.Status == WebExceptionStatus.ServerProtocolViolation) {
					errorDescription = "The server response was not a valid HTTP response";
				} else if (exp.Status == WebExceptionStatus.Timeout) {
					errorDescription = "The server did not respond quickly enough.  The server may be down or overloaded.  Try again later";
				} else {
					errorDescription = exp.Status.ToString();
				}

				throw new BitmapManipException(String.Format("An error occurred while communicating with the server at the URL you provided.  {0}.", 
															 errorDescription),
											   exp);
			} catch (BitmapManipException exp) {
				//Don't modify this one; pass it along
				throw exp;
			} catch (Exception exp) {
				throw new BitmapManipException(String.Format("An error ocurred while retrieving the image from the URL you provided: {0}",
															 exp.Message),
											   exp);
			}
		}

		/// <summary>Converts a bitmap to a JPEG with a specific quality level</summary>
		/// 
		/// <param name="inputBmp">Bitmap to convert</param>
		/// <param name="quality">Specifies a quality from 0 (lowest) to 100 (highest), or -1 to leave
		/// unspecified</param>
		/// 
		/// <returns>A new bitmap object containing the input bitmap converted.
		///     If the destination format and the target format are the same, returns
		///     a clone of the destination bitmap.</returns>
		public static Bitmap ConvertBitmapToJpeg(Bitmap inputBmp, int quality) {
			//If the dest format matches the source format and quality not changing, just clone
			if (inputBmp.RawFormat.Equals(ImageFormat.Jpeg) && quality == -1) {
				return(Bitmap)inputBmp.Clone();
			}

			//Create an in-memory stream which will be used to save
			//the converted image
			System.IO.Stream imgStream = new System.IO.MemoryStream();

			//Get the ImageCodecInfo for the desired target format
			ImageCodecInfo destCodec = FindCodecForType(MimeTypeFromImageFormat(ImageFormat.Jpeg));

			if (destCodec == null) {
				//No codec available for that format
				throw new ArgumentException("The requested format " + 
											MimeTypeFromImageFormat(ImageFormat.Jpeg) + 
											" does not have an available codec installed", 
											"destFormat");
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -