function(options) {
				var self = this;
				var orientation;
				var scale;

				var srcRect = {
					x: 0,
					y: 0,
					width: self.width,
					height: self.height
				};

				var opts = Basic.extendIf({
					width: self.width,
					height: self.height,
					type: self.type || 'image/jpeg',
					quality: 90,
					crop: false,
					fit: true,
					preserveHeaders: true,
					resample: 'default',
					multipass: true
				}, options);

				try {
					if (!self.size) { // only preloaded image objects can be used as source
						throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
					}

					// no way to reliably intercept the crash due to high resolution, so we simply avoid it
					if (self.width > Image.MAX_RESIZE_WIDTH || self.height > Image.MAX_RESIZE_HEIGHT) {
						throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR);
					}

					// take into account orientation tag
					orientation = (self.meta && self.meta.tiff && self.meta.tiff.Orientation) || 1;

					if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation
						var tmp = opts.width;
						opts.width = opts.height;
						opts.height = tmp;
					}

					if (opts.crop) {
						scale = Math.max(opts.width/self.width, opts.height/self.height);

						if (options.fit) {
							// first scale it up or down to fit the original image
							srcRect.width = Math.min(Math.ceil(opts.width/scale), self.width);
							srcRect.height = Math.min(Math.ceil(opts.height/scale), self.height);

							// recalculate the scale for adapted dimensions
							scale = opts.width/srcRect.width;
						} else {
							srcRect.width = Math.min(opts.width, self.width);
							srcRect.height = Math.min(opts.height, self.height);

							// now we do not need to scale it any further
							scale = 1;
						}

						if (typeof(opts.crop) === 'boolean') {
							opts.crop = 'cc';
						}

						switch (opts.crop.toLowerCase().replace(/_/, '-')) {
							case 'rb':
							case 'right-bottom':
								srcRect.x = self.width - srcRect.width;
								srcRect.y = self.height - srcRect.height;
								break;

							case 'cb':
							case 'center-bottom':
								srcRect.x = Math.floor((self.width - srcRect.width) / 2);
								srcRect.y = self.height - srcRect.height;
								break;

							case 'lb':
							case 'left-bottom':
								srcRect.x = 0;
								srcRect.y = self.height - srcRect.height;
								break;

							case 'lt':
							case 'left-top':
								srcRect.x = 0;
								srcRect.y = 0;
								break;

							case 'ct':
							case 'center-top':
								srcRect.x = Math.floor((self.width - srcRect.width) / 2);
								srcRect.y = 0;
								break;

							case 'rt':
							case 'right-top':
								srcRect.x = self.width - srcRect.width;
								srcRect.y = 0;
								break;

							case 'rc':
							case 'right-center':
							case 'right-middle':
								srcRect.x = self.width - srcRect.width;
								srcRect.y = Math.floor((self.height - srcRect.height) / 2);
								break;


							case 'lc':
							case 'left-center':
							case 'left-middle':
								srcRect.x = 0;
								srcRect.y = Math.floor((self.height - srcRect.height) / 2);
								break;

							case 'cc':
							case 'center-center':
							case 'center-middle':
							default:
								srcRect.x = Math.floor((self.width - srcRect.width) / 2);
								srcRect.y = Math.floor((self.height - srcRect.height) / 2);
						}

						// original image might be smaller than requested crop, so - avoid negative values
						srcRect.x = Math.max(srcRect.x, 0);
						srcRect.y = Math.max(srcRect.y, 0);
					} else {
						scale = Math.min(opts.width/self.width, opts.height/self.height);

						// do not upscale if we were asked to not fit it
						if (scale > 1 && !opts.fit) {
							scale = 1;
						}
					}

					this.exec('Image', 'resize', srcRect, scale, opts);
				} catch(ex) {
					// for now simply trigger error event
					self.trigger('error', ex.code);
				}
			}