ImageResizer  3.4.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events
Public Member Functions | Protected Member Functions | List of all members
ImageResizer.Plugins.WicBuilder.WicBuilderPlugin Class Reference
Inheritance diagram for ImageResizer.Plugins.WicBuilder.WicBuilderPlugin:
Inheritance graph
[legend]
Collaboration diagram for ImageResizer.Plugins.WicBuilder.WicBuilderPlugin:
Collaboration graph
[legend]

Public Member Functions

IPlugin Install (Configuration.Config c)
 
bool Uninstall (Configuration.Config c)
 
IEnumerable< IIssueGetIssues ()
 
IEnumerable< string > GetSupportedFileExtensions ()
 If the plugin adds support for new file extensions (such as "psd"), they should be returned by this method. More...
 
- Public Member Functions inherited from ImageResizer.Resizing.AbstractImageProcessor
 AbstractImageProcessor ()
 Creates a new AbstractImageProcessor with no extensions More...
 
 AbstractImageProcessor (IEnumerable< BuilderExtension > extensions)
 Creates a new AbstractImageProcessor which will run the specified extensions with each method call. More...
 
virtual Bitmap DecodeStreamFailed (Stream s, ResizeSettings settings, string optionalPath)
 Extensions are executed until one extension returns a non-null value. This is taken to mean that the error has been resolved. Extensions should not throw an exception unless they wish to cause subsequent extensions to not execute. If extensions throw an ArgumentException or ExternalException, it will be wrapped in an ImageCorruptedException instance. If the Bitmap class is used for decoding, read gdi-bugs.txt and make sure you set b.Tag to new BitmapTag(optionalPath,stream); More...
 
virtual Bitmap DecodeStream (Stream s, ResizeSettings settings, string optionalPath)
 Extend this to support alternate image source formats. If the Bitmap class is used for decoding, read gdi-bugs.txt and make sure you set b.Tag to new BitmapTag(optionalPath,stream); More...
 
- Public Member Functions inherited from ImageResizer.Plugins.IPlugin
IPlugin Install (Config c)
 Installs the plugin in the specified Config instance. The plugin must handle all the work of loading settings, registering the plugin etc. More...
 
bool Uninstall (Config c)
 Uninstalls the plugin. Should reverse all changes made during Install More...
 

Protected Member Functions

override RequestedAction BuildJob (ImageJob job)
 Adds alternate pipeline based on WIC. Invoked by &builder=wic. This method doesn't handle job.DisposeSource or job.DesposeDest or settings filtering, that's handled by ImageBuilder. Handles all the work for turning 'source' into a byte[]/long pair. More...
 
virtual RequestedAction BuildJobWic (byte[] data, long lData, ImageJob job, bool supportsTransparency)
 Decodes the image in byte[] data, performs the image proccessing, and encodes it to job.Dest More...
 
virtual RequestedAction Encode (IWICComponentFactory factory, IWICBitmapSource data, Size imageSize, ImageJob job)
 
- Protected Member Functions inherited from ImageResizer.Resizing.AbstractImageProcessor
virtual void PreLoadImage (ref object source, ref string path, ref bool disposeSource, ref ResizeSettings settings)
 Extend this to allow additional types of source objects to be accepted by transforming them into Bitmap instances. More...
 
virtual Stream GetStream (object source, ResizeSettings settings, ref bool disposeStream, out string path, out bool restoreStreamPosition)
 Extend this to allow additional types of source objects to be accepted by transforming them into Stream instances. First plugin to return a Stream wins. More...
 
virtual RequestedAction PostDecodeStream (ref Bitmap img, ResizeSettings settings)
 Extend this to modify the Bitmap instance after it has been decoded by DecodeStream or DecodeStreamFailed More...
 
virtual void PreAcquireStream (ref object dest, ResizeSettings settings)
 Extend this to allow additional types of destination objects to be accepted by transforming them into a stream. More...
 
virtual RequestedAction BuildJob (ImageResizer.ImageJob job)
 The method to override if you want to replace the entire pipeline. All Build() calls call this method first. Does nothing in ImageBuilder More...
 
virtual RequestedAction buildToStream (Bitmap source, Stream dest, ResizeSettings settings)
 Called for Build() calls that want the result encoded. (Not for Bitmap Build(source,settings) calls. Only override this method if you need to replace the behavior of image encoding and image processing together, such as adding support for resizing multi-page TIFF files or animated GIFs. More...
 
virtual Bitmap buildToBitmap (Bitmap source, ResizeSettings settings, bool transparencySupported)
 Most calls funnel through here. Default behavior configures an ImageState instance and calls Process(imageState); Shouldn't be overriden for any reason I can think of - use the appropriate virtual method under Process(). If an extension returns a Bitmap instance, it will be used instead of the default behavior. Does NOT dispose of 'source' or 'source's underlying stream. More...
 
virtual RequestedAction OnProcess (ImageState s)
 Process.0 First step of the Process() method. Can replace the entire Process method if RequestAction.Cancel is returned. Can be used to add points to translate (for image maps), and also to modify the settings More...
 
virtual RequestedAction PrepareSourceBitmap (ImageState s)
 Process.1 Switches the bitmap to the correct frame or page, and applies source flipping commands. More...
 
virtual RequestedAction PostPrepareSourceBitmap (ImageState s)
 Process.2 Extend this to apply any pre-processing to the source bitmap that needs to occur before Layout begins More...
 
virtual RequestedAction Layout (ImageState s)
 Process.3(Layout).0: This is the last point at which points to translate should be added. Only return RequestedAction.Cancel if you wish to replace the entire Layout sequence logic. More...
 
virtual RequestedAction FlipExistingPoints (ImageState s)
 Process.3(Layout).1: This is where the points in the layout are flipped the same way the source bitmap was flipped (unless their flags specify otherwise) More...
 
virtual RequestedAction LayoutImage (ImageState s)
 Process.3(Layout).2: Rings 'image' and 'imageArea' are added to the layout. More...
 
virtual RequestedAction PostLayoutImage (ImageState s)
 Process.3(Layout).3: Add rings here to insert them between the image area and the padding More...
 
virtual RequestedAction LayoutPadding (ImageState s)
 Process.3(Layout).4: Ring "padding" is added to the layout More...
 
virtual RequestedAction PostLayoutPadding (ImageState s)
 Process.3(Layout).5: Add rings here to insert them between the padding and the border More...
 
virtual RequestedAction LayoutBorder (ImageState s)
 Process.3(Layout).6: Ring "border" is added to the layout More...
 
virtual RequestedAction PostLayoutBorder (ImageState s)
 Process.3(Layout).7: Add rings here to insert them between the border and the effect rings More...
 
virtual RequestedAction LayoutEffects (ImageState s)
 Process.3(Layout).8: Effects such as 'shadow' are added here. More...
 
virtual RequestedAction PostLayoutEffects (ImageState s)
 Process.3(Layout).9: Add rings here to insert them between the effects and the margin More...
 
virtual RequestedAction LayoutMargin (ImageState s)
 Process.3(Layout).10: Margins are added to the layout More...
 
virtual RequestedAction PostLayoutMargin (ImageState s)
 Process.3(Layout).11: Add rings here to insert them around the margin. Rings will be outermost More...
 
virtual RequestedAction LayoutRotate (ImageState s)
 Process.3(Layout).anytime: Occurs when the layout is rotated. May be called anytime during Layout() More...
 
virtual RequestedAction PostLayoutRotate (ImageState s)
 Process.3(Layout).anytime: Occurs after the layout is rotated. May be called anytime during Layout() More...
 
virtual RequestedAction LayoutNormalize (ImageState s)
 Process.3(Layout).anytime: Occurs when the layout is normalized to 0,0. May be called anytime during Layout() More...
 
virtual RequestedAction PostLayoutNormalize (ImageState s)
 Process.3(Layout).anytime: Occurs after the layout is normalized. May be called anytime during Layout() More...
 
virtual RequestedAction LayoutRound (ImageState s)
 Process.3(Layout).anytime: Occurs when the layout point values are rounded to integers. May be called anytime during Layout() More...
 
virtual RequestedAction PostLayoutRound (ImageState s)
 Process.3(Layout).anytime: Occurs after the layout point values are rounded to integers. May be called anytime during Layout() More...
 
virtual RequestedAction EndLayout (ImageState s)
 Process.3(Layout).12: Occurs once layout has finished. No more changes should occur to points or rings in the layout after this method. destSize is calculated here. More...
 
virtual RequestedAction PrepareDestinationBitmap (ImageState s)
 Process.4: The destination bitmap is created and sized based destSize. A graphics object is initialized for rendering. More...
 
virtual RequestedAction Render (ImageState s)
 Process.5(Render) Rendering. Do not return RequestedAction.Cancel unless you want to replace the entire rendering system. More...
 
virtual RequestedAction RenderBackground (ImageState s)
 Process.5(Render).1 The background color is rendered More...
 
virtual RequestedAction PostRenderBackground (ImageState s)
 Process.5(Render).2 After the background color is rendered More...
 
virtual RequestedAction RenderEffects (ImageState s)
 Process.5(Render).3 Effects (such as a drop shadow or outer glow) are rendered More...
 
virtual RequestedAction PostRenderEffects (ImageState s)
 Process.5(Render).4 After outer effects are rendered More...
 
virtual RequestedAction RenderPadding (ImageState s)
 Process.5(Render).5 Image padding is drawn More...
 
virtual RequestedAction PostRenderPadding (ImageState s)
 Process.5(Render).6 After image padding is drawn More...
 
virtual RequestedAction CreateImageAttribues (ImageState s)
 Process.5(Render).7: An ImageAttributes instance is created if it doesn't already exist. More...
 
virtual RequestedAction PostCreateImageAttributes (ImageState s)
 Process.5(Render).8: The ImageAttributes instance exists and can be modified or replaced. More...
 
virtual RequestedAction PreRenderImage (ImageState s)
 Process.5(Render).9: Plugins have a chance to pre-process the source image before it gets rendered, and save it to s.preRenderBitmap More...
 
virtual RequestedAction RenderImage (ImageState s)
 Process.5(Render).10: The image is copied to the destination parallelogram specified by ring 'image'. More...
 
virtual RequestedAction PostRenderImage (ImageState s)
 Process.5(Render).11: After the image is drawn More...
 
virtual RequestedAction RenderBorder (ImageState s)
 Process.5(Render).12: The border is rendered More...
 
virtual RequestedAction PostRenderBorder (ImageState s)
 Process.5(Render).13: After the border is drawn More...
 
virtual RequestedAction PreRenderOverlays (ImageState s)
 Process.5(Render).14: Any last-minute changes before watermarking or overlays are applied More...
 
virtual RequestedAction RenderOverlays (ImageState s)
 Process.5(Render).15: Watermarks can be rendered here. All image processing should be done More...
 
virtual RequestedAction PreFlushChanges (ImageState s)
 Process.5(Render).16: Called before changes are flushed and the graphics object is destroyed. More...
 
virtual RequestedAction FlushChanges (ImageState s)
 Process.5(Render).17: Changes are flushed to the bitmap here and the graphics object is destroyed. More...
 
virtual RequestedAction PostFlushChanges (ImageState s)
 Process.5(Render).18: Changes have been flushed to the bitmap, but the final bitmap has not been flipped yet. More...
 
virtual RequestedAction ProcessFinalBitmap (ImageState s)
 Process.6: Non-rendering changes to the bitmap object occur here, such as flipping. The graphics object is unavailable. More...
 
virtual RequestedAction EndProcess (ImageState s)
 Process.7: Layout and rendering are both complete. More...
 

Additional Inherited Members

- Protected Attributes inherited from ImageResizer.Resizing.AbstractImageProcessor
volatile IEnumerable
< BuilderExtension
exts
 Contains the set of extensions that are called for every method. More...
 

Detailed Description

Definition at line 23 of file WicBuilder.cs.

Member Function Documentation

override RequestedAction ImageResizer.Plugins.WicBuilder.WicBuilderPlugin.BuildJob ( ImageJob  job)
inlineprotected

Adds alternate pipeline based on WIC. Invoked by &builder=wic. This method doesn't handle job.DisposeSource or job.DesposeDest or settings filtering, that's handled by ImageBuilder. Handles all the work for turning 'source' into a byte[]/long pair.

Parameters
job
Returns

Definition at line 48 of file WicBuilder.cs.

48  {
49  if (!"wic".Equals(job.Settings["builder"])) return RequestedAction.None;
50 
51  //Convert the source stream to a byte[] array and length.
52  byte[] data = null;
53  long lData = 0;
54 
55 
56  //This step gets a Stream instance, copies it to a MemoryStream, then accesses the underlying buffer to get the byte[] and length we need.
57  Stream s = null;
58  bool disposeStream = !(job.Source is Stream);
59  long originalPosition = 0;
60  bool restoreStreamPosition = false;
61  try {
62  //Get a Stream instance for the job
63  string path;
64  s = c.CurrentImageBuilder.GetStreamFromSource(job.Source, job.Settings, ref disposeStream, out path, out restoreStreamPosition);
65  if (s == null) return RequestedAction.None; //We don't support the source object!
66  if (job.ResetSourceStream) restoreStreamPosition = true;
67  job.SourcePathData = path;
68 
69  //Save the original stream positione
70  originalPosition = (restoreStreamPosition) ? s.Position : -1;
71 
72  data = StreamExtensions.CopyOrReturnBuffer(s, out lData,false, 0x1000);
73  } finally {
74  if (s != null && restoreStreamPosition && s.CanSeek) s.Seek(originalPosition, SeekOrigin.Begin);
75  if (disposeStream) s.Dispose();
76  }
77 
78  //Ok, now we have our byte[] and length.
79 
80  //Let's find out if transparency is supported.
81  IEncoder managedEncoder = c.Plugins.GetEncoder(job.Settings, job.SourcePathData);
82 
83  bool supportsTransparency = managedEncoder.SupportsTransparency;
84 
85  RequestedAction result = BuildJobWic(data, lData, job, supportsTransparency);
86  GC.KeepAlive(data);
87  return result;
88  }
RequestedAction
What to do about remaining handlers/methods for the specified section
static byte[] CopyOrReturnBuffer(Stream src, out long length, bool entireStream, int chunkSize)
Attempts to return a byte[] array containing the remaining portion of the stream. Unlike CopyToBytes(...
Definition: Stream.cs:189
Provides extension methods for copying streams
Definition: Stream.cs:12
virtual RequestedAction BuildJobWic(byte[] data, long lData, ImageJob job, bool supportsTransparency)
Decodes the image in byte[] data, performs the image proccessing, and encodes it to job...
Definition: WicBuilder.cs:98
An image encoder. Exposes methods for suitability checking, encoding, transparency compatibility chec...
Definition: IEncoder.cs:13
virtual RequestedAction ImageResizer.Plugins.WicBuilder.WicBuilderPlugin.BuildJobWic ( byte[]  data,
long  lData,
ImageJob  job,
bool  supportsTransparency 
)
inlineprotectedvirtual

Decodes the image in byte[] data, performs the image proccessing, and encodes it to job.Dest

Parameters
dataThe buffer containing the encoded image file
lDataThe number of bytes to read
job
supportsTransparency
Returns

Definition at line 98 of file WicBuilder.cs.

98  {
99 
100  ResizeSettings settings = job.Settings; ResizeSettings q = settings;
101  string path = job.SourcePathData;
102 
103  //A list of COM objects to destroy
104  List<object> com = new List<object>();
105  try {
106  //Create the factory
108  com.Add(factory);
109 
110  //Wrap the byte[] with a IWICStream instance
111  var streamWrapper = factory.CreateStream();
112  streamWrapper.InitializeFromMemory(data, (uint)lData);
113  com.Add(streamWrapper);
114 
115  var decoder = factory.CreateDecoderFromStream(streamWrapper, null,
116  WICDecodeOptions.WICDecodeMetadataCacheOnLoad);
117  com.Add(decoder);
118 
119  //Figure out which frame to work with
120  int frameIndex = 0;
121  if (!string.IsNullOrEmpty(q["page"]) && !int.TryParse(q["page"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex))
122  if (!string.IsNullOrEmpty(q["frame"]) && !int.TryParse(q["frame"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex))
123  frameIndex = 0;
124 
125  //So users can use 1-based numbers
126  frameIndex--;
127 
128  if (frameIndex > 0) {
129  int frameCount = (int)decoder.GetFrameCount(); //Don't let the user go past the end.
130  if (frameIndex >= frameCount) frameIndex = frameCount - 1;
131  }
132 
133  IWICBitmapFrameDecode frame = decoder.GetFrame((uint)Math.Max(0,frameIndex));
134  com.Add(frame);
135 
136 
137 
138  WICBitmapInterpolationMode interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeFant;
139  if ("nearest".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor;
140  if ("bicubic".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic;
141  if ("linear".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
142  if ("nearestneighbor".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
143 
144  //Find the original image size
145  uint origWidth, origHeight;
146  frame.GetSize(out origWidth,out origHeight);
147  Size orig = new Size((int)origWidth,(int)origHeight);
148 
149  Guid pixelFormat;
150  frame.GetPixelFormat(out pixelFormat);
151  //Calculate the new size of the image and the canvas.
152  ImageState state = new ImageState(settings, orig, true);
153  c.CurrentImageBuilder.Process(state);
154 
155 
156  Rectangle imageDest = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(state.layout["image"]));
157 
158 
159  IWICBitmapSource imageData = frame;
160  //Are we cropping? then daisy-chain a clipper
161  if (state.copyRect.Left != 0 || state.copyRect.Top != 0 || state.copyRect.Width != state.originalSize.Width || state.copyRect.Height != state.originalSize.Height) {
162 
163  //Cropping is absurdly slow... 4x slower than resizing!
164  //Cropping after resizing (unintuitively) is faster.
165  if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) {
166  double sx = (double)imageDest.Width / (double)state.copyRect.Width;
167  double sy = (double)imageDest.Height / (double)state.copyRect.Height;
168  uint uncroppedDestWidth = (uint)Math.Round(sx * state.originalSize.Width);
169  uint uncroppedDestHeight = (uint)Math.Round(sy * state.originalSize.Height);
170 
171  var scaler = factory.CreateBitmapScaler();
172  scaler.Initialize(imageData, uncroppedDestWidth, uncroppedDestHeight, interpolationMode);
173  com.Add(scaler);
174 
175  //TODO: cropping is not consistent with GDI.
176  var clipper = factory.CreateBitmapClipper();
177  clipper.Initialize(scaler, new WICRect {
178  X = (int)Math.Floor((double)state.copyRect.X * sx),
179  Y = (int)Math.Floor((double)state.copyRect.Y * sy),
180  Width = imageDest.Width,
181  Height = imageDest.Height
182  });
183  com.Add(clipper);
184  imageData = clipper;
185 
186  } else {
187  var clipper = factory.CreateBitmapClipper();
188  clipper.Initialize(imageData, new WICRect { X = (int)state.copyRect.X, Y = (int)state.copyRect.Y, Width = (int)state.copyRect.Width, Height = (int)state.copyRect.Height });
189  com.Add(clipper);
190  imageData = clipper;
191  }
192  //If we're scaling but not cropping.
193  }else if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) {
194  var scaler = factory.CreateBitmapScaler();
195  scaler.Initialize(imageData, (uint)imageDest.Width, (uint)imageDest.Height, interpolationMode);
196  com.Add(scaler);
197  imageData = scaler;
198  }
199 
200 
201 
202  //Are we padding? Then we have to do an intermediate write.
203  if (state.destSize.Width != imageDest.Width || state.destSize.Height != imageDest.Height){
204  byte[] bgcolor = ConversionUtils.ConvertColor(job.Settings.BackgroundColor, pixelFormat);
205 
206  for (int i = 0; i < bgcolor.Length; i++) bgcolor[i] = 255; //White
207 
208  var padder = new WicBitmapPadder(imageData, imageDest.X, imageDest.Y, state.destSize.Width - (imageDest.X + imageDest.Width), state.destSize.Height - (imageDest.Y + imageDest.Height), bgcolor, null);
209  imageData = padder;
210  }
211 
212  //Now encode imageData and be done with it...
213  return Encode(factory, imageData, imageDest.Size, job);
214  } finally {
215  //Manually cleanup all the com reference counts, aggressively
216  while (com.Count > 0) {
217  Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another.
218  com.RemoveAt(com.Count - 1);
219  }
220  }
221  }
Flip vertically (identical to 180 degree rotation)
Encapsulates the state of an image being resized. Can be used to simulate a resize as well as actuall...
Definition: ImageState.cs:15
Flip horizontally
IEnumerable<string> ImageResizer.Plugins.WicBuilder.WicBuilderPlugin.GetSupportedFileExtensions ( )
inline

If the plugin adds support for new file extensions (such as "psd"), they should be returned by this method.

Returns

Implements ImageResizer.Plugins.IFileExtensionPlugin.

Definition at line 266 of file WicBuilder.cs.

266  {
267  return new string[]{"hdp","jxr","wdp"};//Plus the ones already listed by ImageBuilder
268  //We can enumerate available codecs through factory.CreateComponentEnumerator and factory.CreateComponentInfo...
269  //But those codecs only give us Author, CLSID, FriendlyName, SpecVersion, VendorGUID, and Version. No list of supported file extensions.
270  //So maybe it's best to make that user-specified?
271  }

The documentation for this class was generated from the following file: