public void ChangePicture(string bookFolderPath, GeckoElement img, PalasoImage imageInfo, IProgress progress) { var imageFileName = ProcessAndCopyImage(imageInfo, bookFolderPath); img.SetAttribute("src", imageFileName); UpdateMetdataAttributesOnImgElement(img, imageInfo); }
public static void CopyImageMetadataToWholeBook(string folderPath, HtmlDom dom, Metadata metadata, IProgress progress) { progress.WriteStatus("Starting..."); //First update the images themselves int completed = 0; var imgElements = GetImagePaths(folderPath); foreach (string path in imgElements) { progress.ProgressIndicator.PercentCompleted = (int)(100.0 * (float)completed / imgElements.Count()); progress.WriteStatus("Copying to " + Path.GetFileName(path)); using (var image = PalasoImage.FromFile(path)) { image.Metadata = metadata; image.SaveUpdatedMetadataIfItMakesSense(); } ++completed; } //Now update the html attributes which echo some of it, and is used by javascript to overlay displays related to //whether the info is there or missing or whatever. foreach (XmlElement img in dom.SafeSelectNodes("//img")) { UpdateImgMetdataAttributesToMatchImage(folderPath, img, progress, metadata); } }
private bool ShouldSaveAsJpeg(PalasoImage imageInfo) { /* * Note, each guid is VERY SIMILAR. The difference is only in the last 2 digits of the 1st group. * Undefined B96B3CA9 * MemoryBMP B96B3CAA * BMP B96B3CAB * EMF B96B3CAC * WMF B96B3CAD * JPEG B96B3CAE * PNG B96B3CAF * GIF B96B3CB0 * TIFF B96B3CB1 * EXIF B96B3CB2 * Icon B96B3CB5 */ if (ImageFormat.Jpeg.Guid == imageInfo.Image.RawFormat.Guid) { return(true); } if (ImageFormat.Jpeg.Equals(imageInfo.Image.PixelFormat)) //review { return(true); } if (string.IsNullOrEmpty(imageInfo.FileName)) { return(false); } return(new [] { "jpg", "jpeg" }.Contains(Path.GetExtension(imageInfo.FileName).ToLower())); }
//Up through Bloom 3.0, we would make white areas transparent when importing images, in order to make them //look good against the colored background of a book cover. //This caused problems with some PDF viewers, so in Bloom 3.1, we switched to only making them transparent at runtime. //This method allows us to undo that transparency-making. public static void RemoveTransparencyOfImagesInFolder(string folderPath, IProgress progress) { var imageFiles = Directory.GetFiles(folderPath, "*.png"); int completed = 0; foreach (string path in imageFiles) { if (Path.GetFileName(path).ToLowerInvariant() == "placeholder.png") { return; } progress.ProgressIndicator.PercentCompleted = (int)(100.0 * (float)completed / (float)imageFiles.Length); using (var pi = PalasoImage.FromFileRobustly(path)) { // If the image isn't jpeg, and we can't be sure it's already opaque, change the // image to be opaque. As explained above, some PDF viewers don't handle transparent // images very well. if (!AppearsToBeJpeg(pi) && !IsIndexedAndOpaque(pi.Image)) { RemoveTransparency(pi, path, progress); } } completed++; } }
public void Locked_NewOne_False() { using (var pi = new PalasoImage()) { Assert.IsFalse(pi.MetadataLocked); } }
private static string GetImageFileName(string bookFolderPath, PalasoImage imageInfo, bool isJpeg) { string s; if (string.IsNullOrEmpty(imageInfo.FileName) || imageInfo.FileName.StartsWith("tmp")) { // Some images, like from a scanner or camera, won't have a name yet. Some will need a number // in order to differentiate from what is already there. We don't try and be smart somehow and // know when to just replace the existing one with the same name... some other process will have // to remove unused images. s = "image"; int i = 0; string suffix = ""; string extension = isJpeg ? ".jpg" : ".png"; while (File.Exists(Path.Combine(bookFolderPath, s + suffix + extension))) { ++i; suffix = i.ToString(); } return(s + suffix + extension); } else { var extension = isJpeg ? ".jpg" : ".png"; return(Path.GetFileNameWithoutExtension(imageInfo.FileName) + extension); } }
public static Image MakePngBackgroundTransparent(PalasoImage originalImage) { // If the image is indexed and opaque, convert the palette to have a transparent background. This produces // a much smaller image file than the process of redrawing the image with a transparent conversion. That // process always produces a 32-bit RGBA format image. Changing the palette should also be faster than // redrawing in a new size and format. // libgdiplus on Linux doesn't handle Alpha (transparency) information for indexed format images. if (SIL.PlatformUtilities.Platform.IsWindows && ImageUtils.IsIndexedAndOpaque(originalImage.Image)) { var revisedBitmap = originalImage.Image.Clone() as Image; revisedBitmap.Palette = GivePaletteTransparentBackground(revisedBitmap); return(revisedBitmap); } //impose a maximum size because in BL-2871 "Opposites" had about 6k x 6k and we got an ArgumentException //from the new BitMap() var destinationWidth = Math.Min(1000, originalImage.Image.Width); var destinationHeight = (int)((float)originalImage.Image.Height * ((float)destinationWidth / (float)originalImage.Image.Width)); var processedBitmap = new Bitmap(destinationWidth, destinationHeight); using (var g = Graphics.FromImage(processedBitmap)) { var destRect = new Rectangle(0, 0, destinationWidth, destinationHeight); lock (ConvertWhiteToTransparent) { g.DrawImage(originalImage.Image, destRect, 0, 0, originalImage.Image.Width, originalImage.Image.Height, GraphicsUnit.Pixel, ConvertWhiteToTransparent); } } return(processedBitmap); }
private PalasoImage MakeSampleTifImage(string path) { var x = new Bitmap(kSampleImageDimension, kSampleImageDimension); x.Save(path, ImageFormat.Tiff); return(PalasoImage.FromFileRobustly(path)); }
public void Image_CreatedWithImageOnly_GivesSameImage() { Bitmap bitmap = new Bitmap(10, 10); var pi = new PalasoImage(bitmap); Assert.AreEqual(bitmap, pi.Image); }
public void FileName_CreatedWithImageOnly_Null() { using (var pi = PalasoImage.FromImage(new Bitmap(10, 10))) { Assert.IsNull(pi.FileName); } }
private PalasoImage MakeSamplePngImage(string path) { var x = new Bitmap(kSampleImageDimension, kSampleImageDimension); x.Save(path, ImageFormat.Png); x.Dispose(); return(PalasoImage.FromFile(path)); }
private PalasoImage MakeSampleJpegImage(string path) { var x = new Bitmap(kSampleImageDimension, kSampleImageDimension); x.Save(path, ImageFormat.Jpeg); //nb: even if we reload the image from the file, the rawformat will be memory bitmap, not jpg as we'd wish return(PalasoImage.FromFileRobustly(path)); }
public void ShouldChangeFormatToJpeg_OneColor_False() { var path = FileLocationUtilities.GetFileDistributedWithApplication(_pathToTestImages, "bird.png"); string jpegPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName() + ".jpg"); Assert.IsFalse(ImageUtils.TryChangeFormatToJpegIfHelpful(PalasoImage.FromFile(path), jpegPath)); Assert.IsFalse(File.Exists(jpegPath)); }
public void SetImage(PalasoImage image) { _previousImage = image; if (ImageChanged != null) { ImageChanged.Invoke(this, null); } }
/// <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); }
public void FromFile_HugeJPEG_DoesNotCrash() { //nb: trying to reproduce a problem that came up in bloom with this very image, but //i never did get this to crash here PalasoImage.FromFile(@"C:\Users\John\Desktop\hugetestimage.jpg"); PalasoImage.FromFile(@"C:\Users\John\Desktop\hugetestimage.jpg"); PalasoImage.FromFile(@"C:\Users\John\Desktop\hugetestimage.jpg"); PalasoImage.FromFile(@"C:\Users\John\Desktop\hugetestimage.jpg"); }
public void Image_FromFile_GivesImage() { using (Bitmap bitmap = new Bitmap(10, 10)) using (var temp = TempFile.CreateAndGetPathButDontMakeTheFile()) { bitmap.Save(temp.Path); var pi = PalasoImage.FromFile(temp.Path); Assert.AreEqual(10, pi.Image.Width); } }
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 } }
public void FromFile_DoesNotLockFile() { using (Bitmap bitmap = new Bitmap(10, 10)) using (var temp = TempFile.CreateAndGetPathButDontMakeTheFile()) { bitmap.Save(temp.Path); PalasoImage.FromFile(temp.Path); Assert.DoesNotThrow(() => File.Delete(temp.Path)); } }
private void OnEditImageMetdata(DomEventArgs ge) { var imageElement = GetImageNode(ge); if (imageElement == null) { return; } string fileName = imageElement.GetAttribute("src").Replace("%20", " "); var path = Path.Combine(_model.CurrentBook.FolderPath, fileName); using (var imageInfo = PalasoImage.FromFile(path)) { bool looksOfficial = imageInfo.Metadata != null && !string.IsNullOrEmpty(imageInfo.Metadata.CollectionUri); if (looksOfficial) { MessageBox.Show(imageInfo.Metadata.GetSummaryParagraph("en")); return; } Logger.WriteEvent("Showing Metadata Editor For Image"); using (var dlg = new Palaso.UI.WindowsForms.ClearShare.WinFormsUI.MetadataEditorDialog(imageInfo.Metadata)) { if (DialogResult.OK == dlg.ShowDialog()) { imageInfo.Metadata = dlg.Metadata; imageInfo.SaveUpdatedMetadataIfItMakesSense(); imageInfo.Metadata.StoreAsExemplar(Metadata.FileCategory.Image); //update so any overlays on the image are brough up to data var editor = new PageEditingModel(); editor.UpdateMetdataAttributesOnImgElement(imageElement, imageInfo); var answer = MessageBox.Show(LocalizationManager.GetString("EditTab.copyImageIPMetdataQuestion", "Copy this information to all other pictures in this book?", "get this after you edit the metadata of an image"), LocalizationManager.GetString("EditTab.titleOfCopyIPToWholeBooksDialog", "Picture Intellectual Property Information"), MessageBoxButtons.YesNo); if (answer == DialogResult.Yes) { Cursor = Cursors.WaitCursor; try { _model.CopyImageMetadataToWholeBook(dlg.Metadata); // There might be more than one image on this page. Update overlays. _model.RefreshDisplayOfCurrentPage(); } catch (Exception e) { ErrorReport.NotifyUserOfProblem(e, "There was a problem copying the metadata to all the images."); } Cursor = Cursors.Default; } } } } //_model.SaveNow(); //doesn't work: _browser1.WebBrowser.Reload(); }
public void Locked_LoadedButImageHasNoMetadata_False() { var png = new Bitmap(10, 10); using (var temp = new TempFile(false)) { png.Save(temp.Path); var pi = PalasoImage.FromFile(temp.Path); Assert.IsFalse(pi.MetadataLocked); } }
public static void UpdateMetadataAttributesOnImage(GeckoElement img, PalasoImage imageInfo) { //see also Book.UpdateMetadataAttributesOnImage(), which does the same thing but on the document itself, not the browser dom img.SetAttribute("data-copyright", String.IsNullOrEmpty(imageInfo.Metadata.CopyrightNotice) ? "" : imageInfo.Metadata.CopyrightNotice); img.SetAttribute("data-creator", String.IsNullOrEmpty(imageInfo.Metadata.Creator) ? "" : imageInfo.Metadata.Creator); img.SetAttribute("data-license", imageInfo.Metadata.License == null ? "" : imageInfo.Metadata.License.ToString()); }
public void ShowToolboxWith_PreExisting_EnsureRawFormatUnchanged() { Application.EnableVisualStyles(); PalasoImage i = PalasoImage.FromImage(TestImages.logo); using (var dlg = new ImageToolboxDialog(i, "")) { dlg.ShowDialog(); Assert.AreEqual(ImageFormat.Jpeg.Guid, dlg.ImageInfo.Image.RawFormat.Guid); } }
/// <summary> /// Check whether the new image file is the same as the one we already have chosen. /// (or at least the same pathname in the filesystem) /// </summary> /// <remarks> /// See https://silbloom.myjetbrains.com/youtrack/issue/BL-2776. /// If the user goes out of his way to choose the exact same picture file from the /// original location again, a copy will still be created with a slightly revised /// name. Cropping a picture also results in a new copy of the file with the /// revised name. We still need a tool to remove unused picture files from a /// book's folder. (ie, BL-2351) /// </remarks> private bool IsSameFilePath(string bookFolderPath, UrlPathString src, PalasoImage imageInfo) { if (src != null) { var path = Path.Combine(bookFolderPath, src.PathOnly.NotEncoded); if (path == imageInfo.OriginalFilePath) { return(true); } } return(false); }
public void SetImage(PalasoImage image) { if (image == null) { Image = null; } else { _originalFormat = image.Image.RawFormat; Image = image; } }
public void LoadAndSave_DeleteAfter_NothingLocked() { var png = new Bitmap(10, 10); using (var temp = new TempFile(false)) { png.Save(temp.Path); var pi = PalasoImage.FromFile(temp.Path); pi.Metadata.CopyrightNotice = "Copyright 2011 me"; Assert.DoesNotThrow(() => pi.Save(temp.Path)); Assert.DoesNotThrow(() => File.Delete(temp.Path)); } }
private void MakeSamplePngImageWithMetadata(string path) { var x = new Bitmap(10, 10); x.Save(path, ImageFormat.Png); x.Dispose(); using (var img = PalasoImage.FromFile(path)) { img.Metadata.Creator = "joe"; img.Metadata.CopyrightNotice = "Copyright 1999 by me"; img.SaveUpdatedMetadataIfItMakesSense(); } }
protected void MakeSamplePngImageWithMetadata(string path, int width = 10, int height = 10) { var x = new Bitmap(width, height); RobustImageIO.SaveImage(x, path, ImageFormat.Png); x.Dispose(); using (var img = PalasoImage.FromFileRobustly(path)) { img.Metadata.Creator = "joe"; img.Metadata.CopyrightNotice = "Copyright 1999 by me"; RetryUtility.Retry(() => img.SaveUpdatedMetadataIfItMakesSense()); } }
public void FromFileTwiceMaintainsCorrectPath() { using (var bitmap1 = new Bitmap(10, 10)) using (var bitmap2 = new Bitmap(10, 10)) using (var tf1 = TempFile.WithExtension(".png")) using (var tf2 = TempFile.WithExtension(".png")) { bitmap1.Save(tf1.Path); bitmap2.Save(tf2.Path); using (var pi1 = PalasoImage.FromFile(tf1.Path)) using (var pi2 = PalasoImage.FromFile(tf2.Path)) Assert.AreNotEqual(pi1.OriginalFilePath, pi2.OriginalFilePath); } }
protected void MakeSamplePngImageWithMetadata(string path) { var x = new Bitmap(10, 10); x.Save(path, ImageFormat.Png); x.Dispose(); using (var img = PalasoImage.FromFile(path)) { img.Metadata.Creator = "joe"; img.Metadata.CopyrightNotice = "Copyright 1999 by me"; img.Metadata.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.NoDerivatives); img.SaveUpdatedMetadataIfItMakesSense(); } }
public void SetImage(PalasoImage image) { if (image == null) { Image = null; } else { _originalFormat = image.Image.RawFormat; Image = image; CheckForInvalidImage(); } }