/// <summary>
        /// Creates a thumbnail of just the cover image (no title, language name, etc.)
        /// </summary>
        /// <returns>Returns true if successful; false otherwise. </returns>
        internal static bool CreateThumbnailOfCoverImage(Book.Book book, HtmlThumbNailer.ThumbnailOptions options, Action <Image> callback = null)
        {
            var imageSrc = book.GetCoverImagePath();

            if (!IsCoverImageSrcValid(imageSrc, options))
            {
                Debug.WriteLine(book.StoragePageFolder + " does not have a cover image.");
                return(false);
            }
            var size         = Math.Max(options.Width, options.Height);
            var destFilePath = Path.Combine(book.StoragePageFolder, options.FileName);
            // Writing a transparent image to a file, then reading it in again appears to be the only
            // way to get the thumbnail image to draw with the book's cover color background reliably.
            var transparentImageFile = Path.Combine(Path.GetTempPath(), "Bloom", "Transparent", Path.GetFileName(imageSrc));

            Directory.CreateDirectory(Path.GetDirectoryName(transparentImageFile));
            try
            {
                if (RuntimeImageProcessor.MakePngBackgroundTransparent(imageSrc, transparentImageFile))
                {
                    imageSrc = transparentImageFile;
                }
                using (var coverImage = PalasoImage.FromFile(imageSrc))
                {
                    if (imageSrc == transparentImageFile)
                    {
                        coverImage.Image = MakeImageOpaque(coverImage.Image, book.GetCoverColor());
                    }
                    var shouldAddDashedBorder = options.BorderStyle == HtmlThumbNailer.ThumbnailOptions.BorderStyles.Dashed;
                    coverImage.Image = options.CenterImageUsingTransparentPadding ?
                                       ImageUtils.CenterImageIfNecessary(new Size(size, size), coverImage.Image, shouldAddDashedBorder) :
                                       ImageUtils.ResizeImageIfNecessary(new Size(size, size), coverImage.Image, shouldAddDashedBorder);
                    switch (Path.GetExtension(destFilePath).ToLowerInvariant())
                    {
                    case ".jpg":
                    case ".jpeg":
                        ImageUtils.SaveAsTopQualityJpeg(coverImage.Image, destFilePath);
                        break;

                    default:
                        PalasoImage.SaveImageRobustly(coverImage, destFilePath);
                        break;
                    }
                    if (callback != null)
                    {
                        callback(coverImage.Image.Clone() as Image);                            // don't leave GC to chance
                    }
                }
            }
            finally
            {
                if (File.Exists(transparentImageFile))
                {
                    SIL.IO.RobustFile.Delete(transparentImageFile);
                }
            }
            return(true);
        }
Beispiel #2
0
 private static void RemoveTransparency(PalasoImage original, string path, IProgress progress)
 {
     progress.WriteStatus("RemovingTransparency from image: " + Path.GetFileName(path));
     using (var b = new Bitmap(original.Image.Width, original.Image.Height))
     {
         DrawImageWithWhiteBackground(original.Image, b);
         original.Image = b;
         PalasoImage.SaveImageRobustly(original, path);                 // BL-4148: this method preserves existing metadata
     }
 }
Beispiel #3
0
        /// <summary>
        /// Makes the image a png if it's not a jpg and saves in the book's folder.
        /// If the image has a filename, replaces any file with the same name.
        ///
        /// WARNING: imageInfo.Image could be replaced (causing the original to be disposed)
        /// </summary>
        /// <returns>The name of the file, now in the book's folder.</returns>
        public static string ProcessAndSaveImageIntoFolder(PalasoImage imageInfo, string bookFolderPath, bool isSameFile)
        {
            LogMemoryUsage();
            bool isEncodedAsJpeg = false;

            try
            {
                isEncodedAsJpeg = AppearsToBeJpeg(imageInfo);
                if (!isEncodedAsJpeg)
                {
                    // The original imageInfo.Image is disposed of in the setter.
                    // As of now (9/2016) this is safe because there are no other references to it higher in the stack.
                    imageInfo.Image = CreateImageWithoutTransparentBackground(imageInfo.Image);
                }

                var    shouldConvertToJpeg = !isEncodedAsJpeg && ShouldChangeFormatToJpeg(imageInfo.Image);
                string imageFileName;
                if (!shouldConvertToJpeg && isSameFile)
                {
                    imageFileName = imageInfo.FileName;
                }
                else
                {
                    imageFileName = GetFileNameToUseForSavingImage(bookFolderPath, imageInfo, isEncodedAsJpeg || shouldConvertToJpeg);
                }

                if (!Directory.Exists(bookFolderPath))
                {
                    throw new DirectoryNotFoundException(bookFolderPath + " does not exist");
                }

                var destinationPath = Path.Combine(bookFolderPath, imageFileName);
                if (shouldConvertToJpeg)
                {
                    SaveAsTopQualityJpeg(imageInfo.Image, destinationPath);
                }
                PalasoImage.SaveImageRobustly(imageInfo, destinationPath);

                return(imageFileName);

                /* I (Hatton) have decided to stop compressing images until we have a suite of
                 * tests based on a number of image exemplars. Compression can be great, but it
                 * can also lead to very long waits; this is a "first, do no harm" decision.
                 *
                 * //nb: there are cases (undefined) where we get out of memory if we are not operating on a copy
                 * using (var image = new Bitmap(imageInfo.Image))
                 * {
                 *      using (var tmp = new TempFile())
                 *      {
                 *              RobustImageIO.SaveImage(image, tmp.Path, isJpeg ? ImageFormat.Jpeg : ImageFormat.Png);
                 *              SIL.IO.FileUtils.ReplaceFileWithUserInteractionIfNeeded(tmp.Path, destinationPath, null);
                 *      }
                 *
                 * }
                 *
                 * using (var dlg = new ProgressDialogBackground())
                 * {
                 *      dlg.ShowAndDoWork((progress, args) => ImageUpdater.CompressImage(dest, progress));
                 * }*/
            }
            catch (IOException)
            {
                throw;                 //these are informative on their own
            }

            /* No. OutOfMemory is almost meaningless when it comes to image errors. Better not to confuse people
             * catch (OutOfMemoryException error)
             * {
             * //Enhance: it would be great if we could bring up that problem dialog ourselves, and offer this picture as an attachment
             * throw new ApplicationException("Bloom ran out of memory while trying to import the picture. We suggest that you quit Bloom, run it again, and then try importing this picture again. If that fails, please go to the Help menu and choose 'Report a Problem'", error);
             * }*/
            catch (Exception error)
            {
                if (!string.IsNullOrEmpty(imageInfo.FileName) && RobustFile.Exists(imageInfo.OriginalFilePath))
                {
                    var megs = new System.IO.FileInfo(imageInfo.OriginalFilePath).Length / (1024 * 1000);
                    if (megs > 2)
                    {
                        var msg =
                            string.Format(
                                "Bloom was not able to prepare that picture for including in the book. \r\nThis is a rather large image to be adding to a book --{0} Megs--.",
                                megs);
                        if (isEncodedAsJpeg)
                        {
                            msg +=
                                "\r\nNote, this file is a jpeg, which is normally used for photographs, and complex color artwork. Bloom can handle smallish jpegs, large ones are difficult to handle, especialy if memory is limited.";
                        }
                        throw new ApplicationException(msg, error);
                    }
                }

                throw new ApplicationException(
                          "Bloom was not able to prepare that picture for including in the book. We'd like to investigate, so if possible, would you please email it to [email protected]?" +
                          System.Environment.NewLine + imageInfo.FileName, error);
            }
        }