Beispiel #1
0
        private static void CheckBounds(this ProcessState state)
        {
            if (state.RegionHeight == 0 || state.RegionWidth == 0)
            {
                throw new ArgumentException("Width or Height can not be 0");
            }

            if (state.StartX < 0 || state.StartY < 0)
            {
                throw new ArgumentException("X or Y must be unsigned");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Calculates the region, offset and final output image size
        /// </summary>
        /// <param name="request"></param>
        /// <param name="originalWidth">Original width (pixels) of the source image</param>
        /// <param name="originalHeight">Original height (pixels) of the source image</param>
        /// <param name="allowSizeAboveFull">Allow output image dimensions to exceed that of the source image, but constrained by <see cref="ImageRequest.MaxWidth"/>,<see cref="ImageRequest.MaxHeight"/>,<see cref="ImageRequest.MaxArea"/></param>
        /// <returns></returns>
        static public ProcessState GetInterpretedValues(ImageRequest request, int originalWidth, int originalHeight, bool allowSizeAboveFull)
        {
            request.CheckRequest();
            ProcessState state = new ProcessState();

            state.StartX      = state.StartY = state.RegionHeight = state.RegionWidth = 0;
            state.OutputScale = state.ImageScale = 1;
            switch (request.Region.Mode)
            {
            case ImageRegionMode.PercentageRegion:
                state.StartX       = Convert.ToInt32(request.Region.X / 100 * originalWidth);
                state.StartY       = Convert.ToInt32(request.Region.Y / 100 * originalHeight);
                state.OutputWidth  = state.RegionWidth = Convert.ToInt32(request.Region.Width / 100 * originalWidth);
                state.OutputHeight = state.RegionHeight = Convert.ToInt32(request.Region.Height / 100 * originalHeight);
                break;

            case ImageRegionMode.Region:
                state.StartX       = Convert.ToInt32(request.Region.X);
                state.StartY       = Convert.ToInt32(request.Region.Y);
                state.OutputWidth  = state.RegionWidth = Convert.ToInt32(request.Region.Width);
                state.OutputHeight = state.RegionHeight = Convert.ToInt32(request.Region.Height);
                break;

            case ImageRegionMode.Square:
                state.OutputWidth = state.OutputHeight = state.RegionHeight = state.RegionWidth = Math.Min(originalWidth, originalHeight);
                // pick the middle of the image
                state.StartX = state.RegionWidth == originalWidth ? 0 : Convert.ToInt32(Math.Round((originalWidth - originalHeight) / 2f));
                state.StartY = state.RegionHeight == originalHeight ? 0 : Convert.ToInt32(Math.Round((originalHeight - originalWidth) / 2f));

                break;

            default:
                state.OutputWidth  = state.RegionWidth = originalWidth;
                state.OutputHeight = state.RegionHeight = originalHeight;
                break;
            }

            CheckBounds(state);

            switch (request.Size.Mode)
            {
            case ImageSizeMode.Max:
            case ImageSizeMode.Full:
                // no changes needed as scale and OutputWidth/Height are set
                break;

            case ImageSizeMode.PercentageScaled:
                state.OutputWidth  = Convert.ToInt32(state.RegionWidth * request.Size.Percent.Value);
                state.OutputHeight = Convert.ToInt32(state.RegionHeight * request.Size.Percent.Value);
                state.OutputScale  = request.Size.Percent.Value;
                break;

            case ImageSizeMode.Distort:
                float scaledx, scaledy = 1f;

                scaledy = request.Size.Height / (float)state.RegionHeight;
                scaledx = request.Size.Width / (float)state.RegionWidth;

                state.OutputWidth  = Convert.ToInt32(state.RegionWidth * scaledx);
                state.OutputHeight = Convert.ToInt32(state.RegionHeight * scaledy);
                if (scaledx < scaledy)
                {
                    state.OutputScale = scaledx;
                }
                else
                {
                    state.OutputScale = scaledy;
                }
                if (request.Region.Mode != ImageRegionMode.Full)
                {
                    if (scaledx < scaledy)
                    {
                        state.ImageScale = scaledx;
                    }
                    else
                    {
                        state.ImageScale = scaledy;
                    }
                }
                break;

            case ImageSizeMode.MaintainAspectRatio:
                if (request.Size.Width != 0 && request.Size.Height == 0)
                {
                    var scale = request.Size.Width / (float)state.RegionWidth;
                    state.OutputWidth  = Convert.ToInt32(state.RegionWidth * scale);
                    state.OutputHeight = Convert.ToInt32(state.RegionHeight * scale);
                    state.OutputScale  = scale;
                }
                else if (request.Size.Width == 0 && request.Size.Height != 0)
                {
                    var scale = request.Size.Height / (float)state.RegionHeight;
                    state.OutputWidth  = Convert.ToInt32(state.RegionWidth * scale);
                    state.OutputHeight = Convert.ToInt32(state.RegionHeight * scale);
                    state.OutputScale  = scale;
                }
                else
                {
                    var originalScale = originalWidth / (float)originalHeight;
                    var scale         = Math.Min((request.Size.Height / (float)state.RegionHeight), (request.Size.Width / (float)state.RegionWidth));
                    state.OutputWidth  = Convert.ToInt32(state.RegionWidth * scale);
                    state.OutputHeight = Convert.ToInt32(state.RegionHeight * scale);
                    state.OutputScale  = scale;

                    if (request.Region.Mode != ImageRegionMode.Full)
                    {
                        state.ImageScale = scale;
                    }
                }
                break;
            }

            // final bounds reduction
            float max_scale = 1f;

            (state.OutputWidth, state.OutputHeight, max_scale)
                = ScaleOutput(request.MaxWidth, request.MaxHeight, state.OutputWidth, state.OutputHeight, allowSizeAboveFull);
            state.OutputScale = Math.Min(max_scale, state.ImageScale);

            state.CheckBounds();

            return(state);
        }