Example #1
0
		public static void CopyImageToClipboard(PalasoImage image)
		{
			// N.B.: PalasoImage does not handle .svg files
			if(image == null)
				return;
#if __MonoCS__
			// Review: Someone who knows how needs to implement this!
			throw new NotImplementedException("SIL.Windows.Forms.Miscellaneous.PortableClipboard.CopyImageToClipboard() is not yet implemented for Linux");
#else
			if (image.Image == null)
			{
				if (String.IsNullOrEmpty(image.OriginalFilePath))
					return;
				// no image, but a path
				Clipboard.SetFileDropList(new StringCollection() {image.OriginalFilePath});
			}
			else
			{
				if (String.IsNullOrEmpty(image.OriginalFilePath))
					Clipboard.SetImage(image.Image);
				else
				{
					IDataObject clips = new DataObject();
					clips.SetData(DataFormats.UnicodeText, image.OriginalFilePath);
					clips.SetData(DataFormats.Bitmap, image.Image);
					// true here means that the image should remain on the clipboard if the application exits
					Clipboard.SetDataObject(clips,true);
				}
			}
#endif
		}
        private void SetCurrentImageToolTip(PalasoImage image)
        {
            _toolTip.SetToolTip(_currentImageBox, "");

            //enchance: this only uses the "originalpath" version, which may be a lot larger than what we
            //currently have, if we cropped, for example. But I'm loath to save it to disk just to get an accurate size.
            if (image != null && !string.IsNullOrEmpty(image.OriginalFilePath) && File.Exists(image.OriginalFilePath))
            {
                try
                {
                    float size = new System.IO.FileInfo(image.OriginalFilePath).Length;
                    if (size > 1000 * 1024)
                    {
                        _toolTip.SetToolTip(_currentImageBox,
                                            string.Format("{0} {1:N2}M", image.OriginalFilePath, size / (1024f * 1000f)));
                    }
                    else
                    {
                        _toolTip.SetToolTip(_currentImageBox, string.Format("{0} {1:N2}K", image.OriginalFilePath, size / 1024f));
                    }
                }
                catch (Exception error)
                {
                    _toolTip.SetToolTip(_currentImageBox, error.Message);
                }
            }
        }
Example #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="imageInfo">optional (can be null)</param>
 /// <param name="initialSearchString">optional</param>
 public ImageToolboxDialog(PalasoImage imageInfo, string initialSearchString)
 {
     InitializeComponent();
     _imageToolboxControl.ImageInfo           = imageInfo;
     _imageToolboxControl.InitialSearchString = initialSearchString;
     SearchLanguage = "en";              // unless the caller specifies otherwise explicitly
 }
        private void GetImageFileFromSystem()
        {
            try
            {
                SetMode(Modes.SingleImage);
                // The primary thing that OpenFileDialogWithViews buys us is the ability to default to large icons.
                // OpenFileDialogWithViews still doesn't let us read (and thus remember) the selected view.
                using (var dlg = new OpenFileDialogWithViews(OpenFileDialogWithViews.DialogViewTypes.Large_Icons))
                {
                    if (string.IsNullOrEmpty(ImageToolboxSettings.Default.LastImageFolder))
                    {
                        dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
                    }
                    else
                    {
                        dlg.InitialDirectory = ImageToolboxSettings.Default.LastImageFolder;;
                    }

                    dlg.Title = "Choose Picture File".Localize("ImageToolbox.FileChooserTitle", "Title shown for a file chooser dialog brought up by the ImageToolbox");

                    //NB: dissallowed gif because of a .net crash:  http://jira.palaso.org/issues/browse/BL-85
                    dlg.Filter = "picture files".Localize("ImageToolbox.PictureFiles", "Shown in the file-picking dialog to describe what kind of files the dialog is filtering for") + "(*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.bmp)|*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.bmp;";

                    if (DialogResult.OK == dlg.ShowDialog(this.ParentForm))
                    {
                        ImageToolboxSettings.Default.LastImageFolder = Path.GetDirectoryName(dlg.FileName);
                        ImageToolboxSettings.Default.Save();

                        try
                        {
                            _currentImage = PalasoImage.FromFile(dlg.FileName);
                        }
                        catch (Exception err)                         //for example, http://jira.palaso.org/issues/browse/BL-199
                        {
                            var msg = "Sorry, there was a problem loading that image.".Localize(
                                "ImageToolbox.ProblemLoadingImage");
                            if (ImageLoadingExceptionReporter != null)
                            {
                                ImageLoadingExceptionReporter(dlg.FileName, err, msg);
                            }
                            else
                            {
                                ErrorReport.NotifyUserOfProblem(err, msg);
                            }

                            return;
                        }
                        _pictureBox.Image = _currentImage.Image;
                        if (ImageChanged != null)
                        {
                            ImageChanged.Invoke(this, null);
                        }
                    }
                }
            }
            finally
            {
                _actModal = false;
            }
        }
		/// <summary>
		///
		/// </summary>
		/// <param name="imageInfo">optional (can be null)</param>
		/// <param name="initialSearchString">optional</param>
		public ImageToolboxDialog(PalasoImage imageInfo, string initialSearchString)
		{
			InitializeComponent();
			_imageToolboxControl.ImageInfo = imageInfo;
			_imageToolboxControl.InitialSearchString = initialSearchString;
			SearchLanguage = "en";	// unless the caller specifies otherwise explicitly
		}
Example #6
0
        public static bool AppearsToBeJpeg(PalasoImage imageInfo)
        {
            // A user experienced a crash due to a null object in this section of the code.
            // I've added a couple of checks to prevent that kind of crash here.
            if (imageInfo == null || imageInfo.Image == null)
                return false;
            /*
             * 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(imageInfo.Image.RawFormat != null && 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).ToLowerInvariant());
        }
		public ImageToolboxControl()
		{
			InitializeComponent();
			_toolImages = new ImageList();
			ImageInfo = new PalasoImage();
			_copyExemplarMetadata.Font = _editMetadataLink.Font;
			SearchLanguage = "en";	// unless/until the owner specifies otherwise explicitly
		}
Example #8
0
		public void Image_CreatedWithImageOnly_GivesSameImage()
		{
			Bitmap bitmap = new Bitmap(10, 10);
			using (var pi = new PalasoImage(bitmap))
			{
				Assert.AreEqual(bitmap, pi.Image);
			}
		}
 public ImageToolboxControl()
 {
     InitializeComponent();
     _toolImages = new ImageList();
     ImageInfo   = new PalasoImage();
     _copyExemplarMetadata.Font = _editMetadataLink.Font;
     SearchLanguage             = "en";  // unless/until the owner specifies otherwise explicitly
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="bookFolderPath"></param>
        /// <param name="imgOrDivWithBackgroundImage">Can be an XmlElement (during testing)</param>
        /// <param name="imageInfo"></param>
        /// <param name="progress"></param>
        public void ChangePicture(string bookFolderPath, ElementProxy imgOrDivWithBackgroundImage, PalasoImage imageInfo,
			IProgress progress)
        {
            var isSameFile = IsSameFilePath(bookFolderPath, HtmlDom.GetImageElementUrl(imgOrDivWithBackgroundImage), imageInfo);
            var imageFileName = ImageUtils.ProcessAndSaveImageIntoFolder(imageInfo, bookFolderPath, isSameFile);
            HtmlDom.SetImageElementUrl(imgOrDivWithBackgroundImage,
                UrlPathString.CreateFromUnencodedString(imageFileName));
            UpdateMetadataAttributesOnImage(imgOrDivWithBackgroundImage, imageInfo);
        }
 /// <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.NotEncoded);
         if (path == imageInfo.OriginalFilePath)
             return true;
     }
     return false;
 }
        public static void UpdateMetadataAttributesOnImage(ElementProxy imgOrDivWithBackgroundImage, PalasoImage imageInfo)
        {
            //see also Book.UpdateMetadataAttributesOnImage(), which does the same thing but on the document itself, not the browser dom
            imgOrDivWithBackgroundImage.SetAttribute("data-copyright",
                             String.IsNullOrEmpty(imageInfo.Metadata.CopyrightNotice) ? "" : imageInfo.Metadata.CopyrightNotice);

            imgOrDivWithBackgroundImage.SetAttribute("data-creator", String.IsNullOrEmpty(imageInfo.Metadata.Creator) ? "" : imageInfo.Metadata.Creator);

            imgOrDivWithBackgroundImage.SetAttribute("data-license", imageInfo.Metadata.License == null ? "" : imageInfo.Metadata.License.ToString());
        }
Example #13
0
 /// <summary>
 /// Save a PalasoImage to a file, trying several times if needed.
 /// </summary>
 /// <remarks>
 /// This would logically belong in SIL.Core.IO.RobustIO except that PalasoImage is in SIL.Windows.Forms.
 /// </remarks>
 public static void SaveImageRobustly(PalasoImage image, string fileName)
 {
     RetryUtility.Retry(() => image.Save(fileName),
                        RetryUtility.kDefaultMaxRetryAttempts,
                        RetryUtility.kDefaultRetryDelay,
                        new HashSet <Type>
     {
         Type.GetType("System.IO.IOException"),
         Type.GetType("System.Runtime.InteropServices.ExternalException")
     });
 }
 private void OpenFileFromDrag(string path)
 {
     SetMode(Modes.SingleImage);
     _currentImage     = PalasoImage.FromFile(path);
     _pictureBox.Image = _currentImage.Image;
     ImageToolboxSettings.Default.LastImageFolder = Path.GetDirectoryName(path);
     ImageToolboxSettings.Default.Save();
     if (ImageChanged != null)
     {
         ImageChanged.Invoke(this, null);
     }
 }
Example #15
0
 /// <summary>
 /// Load a PalasoImage from a file, trying several times if needed.
 /// </summary>
 /// <remarks>
 /// This would logically belong in SIL.Core.IO.RobustIO except that PalasoImage is in SIL.Windows.Forms.
 /// </remarks>
 public static PalasoImage FromFileRobustly(string path)
 {
     return(RetryUtility.Retry(() => PalasoImage.FromFile(path),
                               RetryUtility.kDefaultMaxRetryAttempts,
                               RetryUtility.kDefaultRetryDelay,
                               new HashSet <Type>
     {
         Type.GetType("System.IO.IOException"),
         // Odd type to catch... but it seems that Image.FromFile (which is called in the bowels of PalasoImage.FromFile)
         // throws OutOfMemoryException when the file is inaccessible.
         // See http://stackoverflow.com/questions/2610416/is-there-a-reason-image-fromfile-throws-an-outofmemoryexception-for-an-invalid-i
         Type.GetType("System.OutOfMemoryException")
     }));
 }
 public void SetImage(PalasoImage image)
 {
     _previousImage         = image;
     _scannerButton.Checked = _cameraButton.Checked = false;
     _currentImage          = image;
     SetMode(Modes.SingleImage);
     if (image == null)
     {
         _pictureBox.Image = null;
     }
     else
     {
         _pictureBox.Image = image.Image;
     }
 }
		private void OnGetFromFileSystemClick(object sender, EventArgs e)
		{
			SetMode(Modes.SingleImage);
#if __MonoCS__
			using (var dlg = new OpenFileDialog())
#else
			// The primary thing that OpenFileDialogWithViews buys us is the ability to default to large icons.
			// OpenFileDialogWithViews still doesn't let us read (and thus remember) the selected view.
			using (var dlg = new OpenFileDialogWithViews(OpenFileDialogWithViews.DialogViewTypes.Large_Icons))
#endif
			{
#if __MonoCS__
				// OpenFileDialogWithViews is Windows-only.  Until we need more of its functionality elsewhere,
				// it's much simpler to implement the one method we need here for Mono/Linux.
				SelectLargeIconView(dlg);
#endif
				if (string.IsNullOrEmpty(ImageToolboxSettings.Default.LastImageFolder))
				{
					dlg.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
				}
				else
				{
					dlg.InitialDirectory = ImageToolboxSettings.Default.LastImageFolder; ;
				}

				//NB: dissallowed gif because of a .net crash:  http://jira.palaso.org/issues/browse/BL-85
				dlg.Filter = "picture files".Localize("ImageToolbox.PictureFiles", "Shown in the file-picking dialog to describe what kind of files the dialog is filtering for")+"(*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.bmp)|*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.bmp;";

				if (DialogResult.OK == dlg.ShowDialog())
				{
					ImageToolboxSettings.Default.LastImageFolder = Path.GetDirectoryName(dlg.FileName);
					ImageToolboxSettings.Default.Save();

					try
					{
						_currentImage = PalasoImage.FromFile(dlg.FileName);
					}
					catch (Exception err) //for example, http://jira.palaso.org/issues/browse/BL-199
					{
						ErrorReport.NotifyUserOfProblem(err,"Sorry, there was a problem loading that image.".Localize("ImageToolbox.ProblemLoadingImage"));
						return;
					}
					_pictureBox.Image = _currentImage.Image;
					if (ImageChanged != null)
						ImageChanged.Invoke(this, null);
				}
			}
		}
Example #18
0
        public static PalasoImage FromFile(string path)
        {
            string tempPath;
            var    i = new PalasoImage
            {
                Image                         = LoadImageWithoutLocking(path, out tempPath),
                FileName                      = Path.GetFileName(path),
                _originalFilePath             = path,
                _pathForSavingMetadataChanges = path,
                Metadata                      = Metadata.FromFile(path),
                _tempFilePath                 = tempPath
            };

            NormalizeImageOrientation(i);
            return(i);
        }
Example #19
0
        /// <summary>
        /// If the image contains metadata indicating that it is mirrored or rotated,
        /// convert it to normal orientation (and remove the metadata).
        /// </summary>
        /// <param name="i"></param>
        private static void NormalizeImageOrientation(PalasoImage i)
        {
            var img = i.Image;

            if (Array.IndexOf(img.PropertyIdList, 274) > -1)
            {
                var orientation = (int)img.GetPropertyItem(274).Value[0];
                switch (orientation)
                {
                case 1:
                    // No rotation required.
                    break;

                case 2:
                    img.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    break;

                case 3:
                    img.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;

                case 4:
                    img.RotateFlip(RotateFlipType.Rotate180FlipX);
                    break;

                case 5:
                    img.RotateFlip(RotateFlipType.Rotate90FlipX);
                    break;

                case 6:
                    img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;

                case 7:
                    img.RotateFlip(RotateFlipType.Rotate270FlipX);
                    break;

                case 8:
                    img.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    break;
                }
                // This EXIF data is now invalid and should be removed.
                img.RemovePropertyItem(274);
            }
            i.Metadata.NormalizeOrientation();             // remove it from metadata too.
        }
 /// <summary>
 /// Clean up any resources being used.
 /// </summary>
 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         _toolImages.Dispose();
         if (_imageInfo != null)
         {
             _imageInfo.Dispose();
             _imageInfo = null;
         }
         if (components != null)
         {
             components.Dispose();
             components = null;
         }
     }
     base.Dispose(disposing);
 }
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				_toolImages.Dispose();
				if (_imageInfo!=null)
				{
					_imageInfo.Dispose();
					_imageInfo = null;
				}
				if (components != null)
				{
					components.Dispose();
					components = null;
				}
			}
			base.Dispose(disposing);
		}
        private void GetFromDevice(ImageAcquisitionService.DeviceKind deviceKind)
        {
            //_pictureBox.Image = SampleImages.sampleScan;
            try
            {
                var acquisitionService = new ImageAcquisitionService(deviceKind);

                var wiaImageFile = acquisitionService.Acquire();
                if (wiaImageFile == null)
                {
                    return;
                }

                var imageFile = ConvertToPngOrJpegIfNotAlready(wiaImageFile);
                _currentImage     = PalasoImage.FromFile(imageFile);
                _pictureBox.Image = _currentImage.Image;

                if (ImageChanged != null)
                {
                    ImageChanged.Invoke(this, null);
                }
            }
            catch (ImageDeviceNotFoundException error)
            {
                _messageLabel.Text = error.Message + Environment.NewLine + Environment.NewLine +
                                     "Note: this program works with devices that have a 'WIA' driver, not the old-style 'TWAIN' driver";
                _messageLabel.Visible = true;
            }
            catch (WIA_Version2_MissingException)
            {
                _messageLabel.Text    = "Windows XP does not come with a crucial DLL that lets you use a WIA scanner with this program. Get a technical person to downloand and follow the directions at http://vbnet.mvps.org/files/updates/wiaautsdk.zip";
                _messageLabel.Visible = true;
            }
            catch (Exception error)
            {
                ErrorReport.NotifyUserOfProblem(error, "Problem Getting Image".Localize("ImageToolbox.ProblemGettingImageFromDevice"));
            }
        }
Example #23
0
        private void OnChangeImage(DomEventArgs ge)
        {
            if(!_model.CanChangeImages())
            {
                MessageBox.Show(
                    LocalizationManager.GetString("EditTab.CantPasteImageLocked",
                        "Sorry, this book is locked down so that images cannot be changed."));
                return;
            }

            var imageElement = GetImageNode(ge);
            if(imageElement == null)
                return;
            string currentPath = HtmlDom.GetImageElementUrl(imageElement).NotEncoded;

            if(!CheckIfLockedAndWarn(currentPath))
                return;
            var target = (GeckoHtmlElement) ge.Target.CastToGeckoElement();
            if(target.ClassName.Contains("licenseImage"))
                return;

            Cursor = Cursors.WaitCursor;

            var imageInfo = new PalasoImage();
            var existingImagePath = Path.Combine(_model.CurrentBook.FolderPath, currentPath);

            //don't send the placeholder to the imagetoolbox... we get a better user experience if we admit we don't have an image yet.
            if(!currentPath.ToLowerInvariant().Contains("placeholder") && RobustFile.Exists(existingImagePath))
            {
                try
                {
                    imageInfo = PalasoImage.FromFileRobustly(existingImagePath);
                }
                catch(Exception e)
                {
                    Logger.WriteMinorEvent("Not able to load image for ImageToolboxDialog: " + e.Message);
                }
            }
            Logger.WriteEvent("Showing ImageToolboxDialog Editor Dialog");
            // Check memory for the benefit of developers.  The user won't see anything.
            SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "about to choose picture", false);
            // Deep in the ImageToolboxDialog, when the user asks to see images from the ArtOfReading,
            // We need to use the Gecko version of the thumbnail viewer, since the original ListView
            // one has a sticky scroll bar in applications that are using Gecko.  On Linux, we also
            // need to use the Gecko version of the text box.  Except that the Gecko version of the
            // text box totally freezes the system if the user is using LinuxMint/cinnamon (ie, Wasta).
            // See https://jira.sil.org/browse/BL-1147.
            ThumbnailViewer.UseWebViewer = true;
            if(SIL.PlatformUtilities.Platform.IsUnix &&
               !(SIL.PlatformUtilities.Platform.IsWasta || SIL.PlatformUtilities.Platform.IsCinnamon))
            {
                TextInputBox.UseWebTextBox = true;
            }
            using(var dlg = new ImageToolboxDialog(imageInfo, null))
            {
                var searchLanguage = Settings.Default.ImageSearchLanguage;
                if(String.IsNullOrWhiteSpace(searchLanguage))
                {
                    // Pass in the current UI language.  We want only the main language part of the tag.
                    // (for example, "zh-Hans" should pass in as "zh".)
                    searchLanguage = Settings.Default.UserInterfaceLanguage;
                    var idx = searchLanguage.IndexOfAny(new char[] {'-', '_'});
                    if(idx > 0)
                        searchLanguage = searchLanguage.Substring(0, idx);
                }

                dlg.SearchLanguage = searchLanguage;
                var result = dlg.ShowDialog();
                // Check memory for the benefit of developers.  The user won't see anything.
                SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "picture chosen or canceled", false);
                if(DialogResult.OK == result && dlg.ImageInfo != null)
                {
                    // var path = MakePngOrJpgTempFileForImage(dlg.ImageInfo.Image);
                    SaveChangedImage(imageElement, dlg.ImageInfo, "Bloom had a problem including that image");
                    // Warn the user if we're starting to use too much memory.
                    SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "picture chosen and saved", true);
                }

                // If the user changed the search language for art of reading, remember their change. But if they didn't
                // touch it, don't remember it. Instead, let it continue to track the UI language so that if
                // they are new and just haven't got around to setting the main UI Language,
                // AOR can automatically start using that when they do.
                if(searchLanguage != dlg.SearchLanguage)
                {
                    //store their language selection even if they hit "cancel"
                    Settings.Default.ImageSearchLanguage = dlg.SearchLanguage;
                    Settings.Default.Save();
                }
            }
            Logger.WriteMinorEvent("Emerged from ImageToolboxDialog Editor Dialog");
            Cursor = Cursors.Default;
            imageInfo.Dispose(); // ensure memory doesn't leak
        }
Example #24
0
 private bool ShouldBailOutBecauseUserAgreedNotToUseJpeg(PalasoImage imageInfo)
 {
     if(ImageUtils.AppearsToBeJpeg(imageInfo) && JpegWarningDialog.ShouldWarnAboutJpeg(imageInfo.Image))
     {
         using(var jpegDialog = new JpegWarningDialog())
         {
             return jpegDialog.ShowDialog() == DialogResult.Cancel;
         }
     }
     else
     {
         return false;
     }
 }
Example #25
0
 void SaveChangedImage(GeckoHtmlElement imageElement, PalasoImage imageInfo, string exceptionMsg)
 {
     try
     {
         if(ShouldBailOutBecauseUserAgreedNotToUseJpeg(imageInfo))
             return;
         _model.ChangePicture(imageElement, imageInfo, new NullProgress());
     }
     catch(System.IO.IOException error)
     {
         ErrorReport.NotifyUserOfProblem(error, error.Message);
     }
     catch(ApplicationException error)
     {
         ErrorReport.NotifyUserOfProblem(error, error.Message);
     }
     catch(Exception error)
     {
         ErrorReport.NotifyUserOfProblem(error, exceptionMsg);
     }
 }
Example #26
0
		public void Locked_NewOne_False()
		{
			using (var pi = new PalasoImage())
			{
				Assert.IsFalse(pi.MetadataLocked);
			}
		}
Example #27
0
		public static PalasoImage FromFile(string path)
		{
			string tempPath;
			var i = new PalasoImage
			{
				Image = LoadImageWithoutLocking(path, out tempPath),
				FileName = Path.GetFileName(path),
				_originalFilePath = path,
				_pathForSavingMetadataChanges = path,
				Metadata = Metadata.FromFile(path),
				_tempFilePath = tempPath
			};
			NormalizeImageOrientation(i);
			return i;
		}
Example #28
0
		/// <summary>
		/// If the image contains metadata indicating that it is mirrored or rotated,
		/// convert it to normal orientation (and remove the metadata).
		/// </summary>
		/// <param name="i"></param>
		private static void NormalizeImageOrientation(PalasoImage i)
		{
			var img = i.Image;
			if (Array.IndexOf(img.PropertyIdList, 274) > -1)
			{
				var orientation = (int)img.GetPropertyItem(274).Value[0];
				switch (orientation)
				{
					case 1:
						// No rotation required.
						break;
					case 2:
						img.RotateFlip(RotateFlipType.RotateNoneFlipX);
						break;
					case 3:
						img.RotateFlip(RotateFlipType.Rotate180FlipNone);
						break;
					case 4:
						img.RotateFlip(RotateFlipType.Rotate180FlipX);
						break;
					case 5:
						img.RotateFlip(RotateFlipType.Rotate90FlipX);
						break;
					case 6:
						img.RotateFlip(RotateFlipType.Rotate90FlipNone);
						break;
					case 7:
						img.RotateFlip(RotateFlipType.Rotate270FlipX);
						break;
					case 8:
						img.RotateFlip(RotateFlipType.Rotate270FlipNone);
						break;
				}
				// This EXIF data is now invalid and should be removed.
				img.RemovePropertyItem(274);
			}
			i.Metadata.NormalizeOrientation(); // remove it from metadata too.
		}
		private void SetCurrentImageToolTip(PalasoImage image)
		{
			_toolTip.SetToolTip(_currentImageBox, "");

			//enchance: this only uses the "originalpath" version, which may be a lot larger than what we
			//currently have, if we cropped, for example. But I'm loath to save it to disk just to get an accurate size.
			if (image!=null && !string.IsNullOrEmpty(image.OriginalFilePath) && File.Exists(image.OriginalFilePath))
			{
				try
				{
					float size = new System.IO.FileInfo(image.OriginalFilePath).Length;
					if (size > 1000*1024)
						_toolTip.SetToolTip(_currentImageBox,
											string.Format("{0} {1:N2}M", image.OriginalFilePath, size/(1024f*1000f)));
					else
					{
						_toolTip.SetToolTip(_currentImageBox, string.Format("{0} {1:N2}K", image.OriginalFilePath, size/1024f));
					}
				}
				catch (Exception error)
				{
					_toolTip.SetToolTip(_currentImageBox, error.Message);
				}
			}
		}
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			PalasoImage palasoImage1 = new PalasoImage();
			Metadata metadata1 = new Metadata();
			this._cancelButton = new System.Windows.Forms.Button();
			this._okButton = new System.Windows.Forms.Button();
			this._imageToolboxControl = new ImageToolboxControl();
			this._L10NSharpExtender = new L10NSharp.UI.L10NSharpExtender(this.components);
			((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).BeginInit();
			this.SuspendLayout();
			//
			// _cancelButton
			//
			this._cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this._L10NSharpExtender.SetLocalizableToolTip(this._cancelButton, null);
			this._L10NSharpExtender.SetLocalizationComment(this._cancelButton, null);
			this._L10NSharpExtender.SetLocalizingId(this._cancelButton, "Common.CancelButton");
			this._cancelButton.Location = new System.Drawing.Point(799, 457);
			this._cancelButton.Name = "_cancelButton";
			this._cancelButton.Size = new System.Drawing.Size(75, 23);
			this._cancelButton.TabIndex = 1;
			this._cancelButton.Text = "&Cancel";
			this._cancelButton.UseVisualStyleBackColor = true;
			this._cancelButton.Click += new System.EventHandler(this._cancelButton_Click);
			//
			// _okButton
			//
			this._okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this._L10NSharpExtender.SetLocalizableToolTip(this._okButton, null);
			this._L10NSharpExtender.SetLocalizationComment(this._okButton, null);
			this._L10NSharpExtender.SetLocalizingId(this._okButton, "Common.OKButton");
			this._okButton.Location = new System.Drawing.Point(718, 457);
			this._okButton.Name = "_okButton";
			this._okButton.Size = new System.Drawing.Size(75, 23);
			this._okButton.TabIndex = 2;
			this._okButton.Text = "&OK";
			this._okButton.UseVisualStyleBackColor = true;
			this._okButton.Click += new System.EventHandler(this._okButton_Click);
			//
			// imageToolboxControl1
			//
			this._imageToolboxControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
			| System.Windows.Forms.AnchorStyles.Left)
			| System.Windows.Forms.AnchorStyles.Right)));
			this._imageToolboxControl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
			this._imageToolboxControl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			palasoImage1.Image = null;
			metadata1.AttributionUrl = null;
			metadata1.CollectionName = null;
			metadata1.CollectionUri = null;
			metadata1.CopyrightNotice = "";
			metadata1.Creator = null;
			metadata1.HasChanges = true;
			metadata1.License = null;
			palasoImage1.Metadata = metadata1;
			palasoImage1.MetadataLocked = false;
			this._imageToolboxControl.ImageInfo = palasoImage1;
			this._imageToolboxControl.InitialSearchString = null;
			this._L10NSharpExtender.SetLocalizableToolTip(this._imageToolboxControl, null);
			this._L10NSharpExtender.SetLocalizationComment(this._imageToolboxControl, null);
			this._L10NSharpExtender.SetLocalizationPriority(this._imageToolboxControl, L10NSharp.LocalizationPriority.NotLocalizable);
			this._L10NSharpExtender.SetLocalizingId(this._imageToolboxControl, "ImageToolbox.ImageToolboxDialog.ImageToolboxControl");
			this._imageToolboxControl.Location = new System.Drawing.Point(1, 1);
			this._imageToolboxControl.Name = "_imageToolboxControl";
			this._imageToolboxControl.Size = new System.Drawing.Size(873, 450);
			this._imageToolboxControl.TabIndex = 3;
			//
			// _L10NSharpExtender
			//
			this._L10NSharpExtender.LocalizationManagerId = "Palaso";
			this._L10NSharpExtender.PrefixForNewItems = "ImageToolbox";
			//
			// ImageToolboxDialog
			//
			this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.CancelButton = this._cancelButton;
			this.ClientSize = new System.Drawing.Size(886, 485);
			this.Controls.Add(this._imageToolboxControl);
			this.Controls.Add(this._okButton);
			this.Controls.Add(this._cancelButton);
			this._L10NSharpExtender.SetLocalizableToolTip(this, null);
			this._L10NSharpExtender.SetLocalizationComment(this, null);
			this._L10NSharpExtender.SetLocalizingId(this, "ImageToolbox.ImageToolboxWindowTitle");
			this.MinimumSize = new System.Drawing.Size(732, 432);
			this.Name = "ImageToolboxDialog";
			this.ShowIcon = false;
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "Image Toolbox";
			this.Load += new System.EventHandler(this.ImageToolboxDialog_Load);
			((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).EndInit();
			this.ResumeLayout(false);

		}
Example #31
0
        public void ChangePicture(GeckoHtmlElement img, PalasoImage imageInfo, IProgress progress)
        {
            try
            {
                Logger.WriteMinorEvent("Starting ChangePicture {0}...", imageInfo.FileName);
                var editor = new PageEditingModel();
                editor.ChangePicture(CurrentBook.FolderPath, new ElementProxy(img), imageInfo, progress);

                // We need to save so that when asked by the thumbnailer, the book will give the proper image
                SaveNow();

                // BL-3717: if we cleanup unused image files whenever we change a picture then Cut can lose
                // all of an image's metadata (because the actual file is missing from the book folder when we go to
                // paste in the image that was copied onto the clipboard, which doesn't have metadata.)
                // Let's only do this on ExpensiveIntialization() when loading a book.
                //CurrentBook.Storage.CleanupUnusedImageFiles();

                // But after saving, we need the non-cleaned version back there
                _view.UpdateSingleDisplayedPage(_pageSelection.CurrentSelection);

                _view.UpdateThumbnailAsync(_pageSelection.CurrentSelection);
                Logger.WriteMinorEvent("Finished ChangePicture {0} (except for async thumbnail) ...", imageInfo.FileName);
                Analytics.Track("Change Picture");
                Logger.WriteEvent("ChangePicture {0}...", imageInfo.FileName);

            }
            catch (Exception e)
            {
                var msg = LocalizationManager.GetString("Errors.ProblemImportingPicture","Bloom had a problem importing this picture.");
                ErrorReport.NotifyUserOfProblem(e, msg+Environment.NewLine+e.Message);
            }
        }
		private void OpenFileFromDrag(string path)
		{
			SetMode(Modes.SingleImage);
			_currentImage = PalasoImage.FromFile(path);
			_pictureBox.Image = _currentImage.Image;
			ImageToolboxSettings.Default.LastImageFolder = Path.GetDirectoryName(path);
			ImageToolboxSettings.Default.Save();
			if (ImageChanged != null)
				ImageChanged.Invoke(this, null);
		}
Example #33
0
 public static void SavePalasoImage(PalasoImage image, string path)
 {
     RetryUtility.Retry(() => image.Save(path));
 }
		public void SetImage(PalasoImage image)
		{
			_previousImage = image;
			_scannerButton.Checked = _cameraButton.Checked = false;
			_currentImage = image;
			SetMode(Modes.SingleImage);
			if (image == null)
			{
				_pictureBox.Image = null;
			}
			else
			{
				_pictureBox.Image = image.Image;
			}
		}
		private void GetFromDevice(ImageAcquisitionService.DeviceKind deviceKind)
		{
	  //_pictureBox.Image = SampleImages.sampleScan;
			try
			{
				var acquisitionService = new ImageAcquisitionService(deviceKind);

				var wiaImageFile = acquisitionService.Acquire();
				if (wiaImageFile == null)
					return;

				var imageFile  = ConvertToPngOrJpegIfNotAlready(wiaImageFile);
				_currentImage = PalasoImage.FromFile(imageFile);
				_pictureBox.Image = _currentImage.Image;

				if (ImageChanged != null)
					ImageChanged.Invoke(this, null);
			}
			catch (ImageDeviceNotFoundException error)
			{
				_messageLabel.Text = error.Message + Environment.NewLine +Environment.NewLine+
									 "Note: this program works with devices that have a 'WIA' driver, not the old-style 'TWAIN' driver";
				_messageLabel.Visible = true;
			}
			catch (WIA_Version2_MissingException error)
			{
				_messageLabel.Text = "Windows XP does not come with a crucial DLL that lets you use a WIA scanner with this program. Get a technical person to downloand and follow the directions at http://vbnet.mvps.org/files/updates/wiaautsdk.zip";
				_messageLabel.Visible = true;
			}
			catch (Exception error)
			{
				ErrorReport.NotifyUserOfProblem(error, "Problem Getting Image".Localize("ImageToolbox.ProblemGettingImageFromDevice"));
			}
		}
Example #36
0
 private static string GetFileNameToUseForSavingImage(string bookFolderPath, PalasoImage imageInfo, bool isJpeg)
 {
     var extension = isJpeg ? ".jpg" : ".png";
     // 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.
     string basename;
     if (string.IsNullOrEmpty(imageInfo.FileName) || imageInfo.FileName.StartsWith("tmp"))
     {
         basename = "image";
     }
     else
     {
         // Even pictures that aren't obviously unnamed or temporary may have the same name.
         // See https://silbloom.myjetbrains.com/youtrack/issue/BL-2627 ("Weird Image Problem").
         basename = Path.GetFileNameWithoutExtension(imageInfo.FileName);
     }
     var i = 0;
     var suffix = "";
     while (RobustFile.Exists(Path.Combine(bookFolderPath, basename + suffix + extension)))
     {
         ++i;
         suffix = i.ToString(CultureInfo.InvariantCulture);
     }
     return basename + suffix + extension;
 }
Example #37
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);
                }
                RobustIO.SavePalasoImage(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())
                    {
                        SIL.IO.RobustIO.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);
            }
        }
		public void SetImage(PalasoImage image)
		{
			_previousImage = image;
			if(ImageChanged!=null)
				ImageChanged.Invoke(this,null);
		}
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            PalasoImage palasoImage1 = new PalasoImage();
            Metadata    metadata1    = new Metadata();

            this._cancelButton        = new System.Windows.Forms.Button();
            this._okButton            = new System.Windows.Forms.Button();
            this._imageToolboxControl = new ImageToolboxControl();
            this._L10NSharpExtender   = new L10NSharp.UI.L10NSharpExtender(this.components);
            ((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).BeginInit();
            this.SuspendLayout();
            //
            // _cancelButton
            //
            this._cancelButton.Anchor       = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this._L10NSharpExtender.SetLocalizableToolTip(this._cancelButton, null);
            this._L10NSharpExtender.SetLocalizationComment(this._cancelButton, null);
            this._L10NSharpExtender.SetLocalizingId(this._cancelButton, "Common.CancelButton");
            this._cancelButton.Location = new System.Drawing.Point(799, 457);
            this._cancelButton.Name     = "_cancelButton";
            this._cancelButton.Size     = new System.Drawing.Size(75, 23);
            this._cancelButton.TabIndex = 1;
            this._cancelButton.Text     = "&Cancel";
            this._cancelButton.UseVisualStyleBackColor = true;
            this._cancelButton.Click += new System.EventHandler(this._cancelButton_Click);
            //
            // _okButton
            //
            this._okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._L10NSharpExtender.SetLocalizableToolTip(this._okButton, null);
            this._L10NSharpExtender.SetLocalizationComment(this._okButton, null);
            this._L10NSharpExtender.SetLocalizingId(this._okButton, "Common.OKButton");
            this._okButton.Location = new System.Drawing.Point(718, 457);
            this._okButton.Name     = "_okButton";
            this._okButton.Size     = new System.Drawing.Size(75, 23);
            this._okButton.TabIndex = 2;
            this._okButton.Text     = "&OK";
            this._okButton.UseVisualStyleBackColor = true;
            this._okButton.Click += new System.EventHandler(this._okButton_Click);
            //
            // imageToolboxControl1
            //
            this._imageToolboxControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                                                                                      | System.Windows.Forms.AnchorStyles.Left)
                                                                                     | System.Windows.Forms.AnchorStyles.Right)));
            this._imageToolboxControl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
            this._imageToolboxControl.BorderStyle  = System.Windows.Forms.BorderStyle.FixedSingle;
            palasoImage1.Image                            = null;
            metadata1.AttributionUrl                      = null;
            metadata1.CollectionName                      = null;
            metadata1.CollectionUri                       = null;
            metadata1.CopyrightNotice                     = "";
            metadata1.Creator                             = null;
            metadata1.HasChanges                          = true;
            metadata1.License                             = null;
            palasoImage1.Metadata                         = metadata1;
            palasoImage1.MetadataLocked                   = false;
            this._imageToolboxControl.ImageInfo           = palasoImage1;
            this._imageToolboxControl.InitialSearchString = null;
            this._L10NSharpExtender.SetLocalizableToolTip(this._imageToolboxControl, null);
            this._L10NSharpExtender.SetLocalizationComment(this._imageToolboxControl, null);
            this._L10NSharpExtender.SetLocalizationPriority(this._imageToolboxControl, L10NSharp.LocalizationPriority.NotLocalizable);
            this._L10NSharpExtender.SetLocalizingId(this._imageToolboxControl, "ImageToolbox.ImageToolboxDialog.ImageToolboxControl");
            this._imageToolboxControl.Location = new System.Drawing.Point(1, 1);
            this._imageToolboxControl.Name     = "_imageToolboxControl";
            this._imageToolboxControl.Size     = new System.Drawing.Size(873, 450);
            this._imageToolboxControl.TabIndex = 3;
            //
            // _L10NSharpExtender
            //
            this._L10NSharpExtender.LocalizationManagerId = "Palaso";
            this._L10NSharpExtender.PrefixForNewItems     = "ImageToolbox";
            //
            // ImageToolboxDialog
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            this.AutoScaleMode       = System.Windows.Forms.AutoScaleMode.Dpi;
            this.CancelButton        = this._cancelButton;
            this.ClientSize          = new System.Drawing.Size(886, 485);
            this.Controls.Add(this._imageToolboxControl);
            this.Controls.Add(this._okButton);
            this.Controls.Add(this._cancelButton);
            this._L10NSharpExtender.SetLocalizableToolTip(this, null);
            this._L10NSharpExtender.SetLocalizationComment(this, null);
            this._L10NSharpExtender.SetLocalizingId(this, "ImageToolbox.ImageToolboxWindowTitle");
            this.MinimumSize   = new System.Drawing.Size(732, 432);
            this.Name          = "ImageToolboxDialog";
            this.ShowIcon      = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text          = "Image Toolbox";
            this.Load         += new System.EventHandler(this.ImageToolboxDialog_Load);
            ((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).EndInit();
            this.ResumeLayout(false);
        }