/// <summary> /// Image preparing process. Resizing and fixing quality. /// </summary> /// <param name="originalImage">Original image</param> /// <param name="preComplementWidth">Width used when resizing</param> /// <returns>Grayscaled image for descewing</returns> private static KrecImage PrepareImageForDeskewing(KrecImage originalImage, out int preComplementWidth) { if (originalImage.HorizontalResolution > maxDpi) { // TODO: make k be integer to avoid resampling errors double k = maxDpi / originalImage.HorizontalResolution; originalImage = ImageSizesModifier.CompressImageToNewSizes(originalImage, (int)Math.Round(originalImage.Width * k), (int)Math.Round(originalImage.Height * k)); } KrecImage projectionImage; preComplementWidth = Math.Min(projectionSideWidth, originalImage.Width); if (originalImage.Height < maxCompletedSideWith && originalImage.Width < maxCompletedSideWith) //имитирует поведение прошлого сжимателя { int dx = (maxCompletedSideWith - originalImage.Width) / 2; int dy = (maxCompletedSideWith - originalImage.Height) / 2; int newWidth = projectionSideWidth - dx; int newHeight = projectionSideWidth - dy; double k = Math.Max((double)originalImage.Height / newHeight, (double)originalImage.Width / newWidth); var compressedImage = ImageSizesModifier.CompressImageToNewSizes(originalImage, (int)(originalImage.Width / k), (int)(originalImage.Height / k)); compressedImage = BitmapProcessor.AlignImageBackround(compressedImage); preComplementWidth = (int)(originalImage.Width / k); projectionImage = ImageSizesModifier.GetImageWithPowerOf2Side(compressedImage, projectionSideWidth); } else { var alignedImage = BitmapProcessor.AlignImageBackround(originalImage); projectionImage = ImageSizesModifier.GetImageWithPowerOf2Side(alignedImage, projectionSideWidth); } return(projectionImage); }
/// <summary> /// Get coordinates of rectangle from deskewed projected image in original image /// </summary> /// <param name="projectedRectangle">Rectangle from deskewed projected image</param> /// <param name="projectedImageWidth">Projected image width (before deskewing)</param> /// <param name="projectedImageHeight">Projected image height (before deskewing)</param> /// <param name="preComplementImageWidth">Width of image before it was completed to power of 2</param> /// <param name="preComplementImageHeight">Height of image before it was completed to power of 2</param> /// <param name="originalImageWidth">Original image width</param> /// <param name="originalImageHeight">Original image Height</param> /// <param name="rotationAngle">Images skew angle</param> /// <returns>Rectangle in original image</returns> private static Rectangle GetUnprojectedRectangle(Rectangle projectedRectangle, int projectedImageWidth, int projectedImageHeight, int preComplementImageWidth, int preComplementImageHeight, int originalImageWidth, int originalImageHeight, double rotationAngle) { var points = new[] { new Point(projectedRectangle.Left, projectedRectangle.Top), new Point(projectedRectangle.Right, projectedRectangle.Bottom) }; var rotatedPoints = ImageSizesModifier.GetPointsBeforeRotation(points, -rotationAngle, projectedImageWidth, projectedImageHeight); var scale = (double)preComplementImageWidth / originalImageWidth; var dy = (projectedImageHeight - preComplementImageHeight) / 2; var dx = (projectedImageWidth - preComplementImageWidth) / 2; var descaledPoints = rotatedPoints .Select(p => new Point((int)((p.X - dx) / scale), (int)((p.Y - dy) / scale))).ToList(); var result = ImageSizesModifier .RotatePoints(descaledPoints, -rotationAngle, originalImageWidth, originalImageHeight).ToList(); return(new Rectangle(result[0].X, result[0].Y, result[1].X - result[0].X, result[1].Y - result[0].Y)); }