static PriceRange GetPriceRange(string caption, double confidence, float expensiveMultiplier, Random rnd) { PriceRange priceRange; priceRange.lowPrice = 0; priceRange.highPrice = 0; // Longer captions means higher prices foreach (char c in caption) { priceRange.highPrice += c; } // Randomly increase price priceRange.highPrice *= (int)(1.0f + rnd.NextDouble() * 30.0f); priceRange.highPrice = (int)(priceRange.highPrice * expensiveMultiplier); priceRange.highPrice *= 2; // General multiplier to inflate prices priceRange.lowPrice = (int)(priceRange.highPrice * confidence); PriceRange roundedRange = PriceRange.RoundPrices(priceRange); return(roundedRange); }
public static Bitmap ComposeImage(Bitmap sourceImage, string descriptionText, float confidence, bool isOld, bool isBlackAndWhitePhoto, float expensiveMultiplier, bool isPainting, bool isSign, int?extractedYear, string extractedLocale, Random random) { Bitmap drawnBitmap = null; if (isPainting || isSign) { drawnBitmap = ImageTransforms.ComposeImageOntoPhoto(sourceImage); } else { drawnBitmap = sourceImage.Clone(); } PriceRange priceRange = GetPriceRange(descriptionText, confidence, expensiveMultiplier, random); int year = GetYear(drawnBitmap, isOld, isBlackAndWhitePhoto, extractedYear); string localePhrase = (extractedLocale != null ? (", " + extractedLocale) : ""); string fullCaption = descriptionText + String.Format(" (ca. {0}{1})\n ${2}-${3}", year, localePhrase, PriceRange.FormatPrice(priceRange.lowPrice), PriceRange.FormatPrice(priceRange.highPrice)); Bitmap footerImage = LoadImage(LoadImageType.Source, "footer.png"); float scale = (float)drawnBitmap.Width / (float)footerImage.Width; float footerHeight = scale * footerImage.Height; float footerOriginY = drawnBitmap.Height - footerHeight; float textOriginY = footerOriginY + 10.0f * scale; float textOriginX = 200.0f * scale; int fontSize = (int)(33 * scale); FontFamily family = GetCaptionFontFamily(); Font font = new Font(family, fontSize, FontStyle.Bold); TextGraphicsOptions textGraphicsOptions = new TextGraphicsOptions(); textGraphicsOptions.TextOptions.WrapTextWidth = drawnBitmap.Width - textOriginX - 10; AffineTransformBuilder footerTransformBuilder = new AffineTransformBuilder() .AppendScale(new SizeF(scale, scale)); footerImage.Mutate(x => x.Transform(footerTransformBuilder)); drawnBitmap.Mutate(x => x.DrawImage(footerImage, new SixLabors.ImageSharp.Point(0, (int)footerOriginY), new GraphicsOptions()) .DrawText(textGraphicsOptions, fullCaption, font, NamedColors.White, new PointF(textOriginX + 1, textOriginY + 1))); return(drawnBitmap); }
public static void PriceRangesAreRoundedToAppealingNumbers(int inLowPrice, int inHighPrice, int expectedRoundedLowPrice, int expectedRoundedHighPrice) { PriceRange inputRange = new PriceRange { lowPrice = inLowPrice, highPrice = inHighPrice, }; PriceRange roundedRange = PriceRange.RoundPrices(inputRange); // Input range shouldn't be changed Assert.Equal(inLowPrice, inputRange.lowPrice); Assert.Equal(inHighPrice, inputRange.highPrice); Assert.Equal(expectedRoundedLowPrice, roundedRange.lowPrice); Assert.Equal(expectedRoundedHighPrice, roundedRange.highPrice); }
public static PriceRange RoundPrices(PriceRange inputRange) { PriceRange roundedRange = inputRange; // Get the order of magnitude of the higher price. int highPriceOrder = (int)Math.Floor(Math.Log10(roundedRange.highPrice)); highPriceOrder -= 1; // subtract 1 to keep two meaningful digits on at least the high price if (highPriceOrder <= 0) { // If the prices are two small, exit early return(roundedRange); } int highPriceScale = (int)Math.Pow(10, highPriceOrder); // Use integer division to truncate off the end roundedRange.highPrice = (roundedRange.highPrice / highPriceScale) * highPriceScale; if (roundedRange.lowPrice / highPriceScale > 0) { // If the prices are generally close we can use the high price's // scale to round the low price. This is usually nice to read roundedRange.lowPrice = (roundedRange.lowPrice / highPriceScale) * highPriceScale; } else { // If the prices are too different, round the low price on its own int lowPriceOrder = (int)Math.Floor(Math.Log10(roundedRange.lowPrice)); // Don't subtract anything from the low price order. The prices // are different enough that we only want one meaningful digit. if (lowPriceOrder > 0) { int lowPriceScale = (int)Math.Pow(10, lowPriceOrder); roundedRange.lowPrice = (roundedRange.lowPrice / lowPriceScale) * lowPriceScale; } } return(roundedRange); }
public static void PriceStringsAreFormattedCorrectly(int price, string expectedFormattedString) { Assert.Equal(expectedFormattedString, PriceRange.FormatPrice(price)); }