Example #1
0
        /// <summary>
        ///   Creates a multiscreen wallpaper from multiple <see cref="Wallpaper" /> objects (from multiple images).
        /// </summary>
        /// <remarks>
        ///   <para>
        ///     Use a low <paramref name="scaleFactor" /> to create preview images.
        ///   </para>
        ///   <para>
        ///     Only set <paramref name="useWindowsFix" /> to <c>true</c> if you are planning to apply the generated
        ///     image on the Windows Desktop.
        ///   </para>
        /// </remarks>
        /// <param name="wallpapers">
        ///   A collection containing the <see cref="Wallpaper" /> objects to use.
        /// </param>
        /// <param name="scaleFactor">
        ///   Defines the factor to scale the created image. Decrease this value to speed up the drawing process of preview images.
        /// </param>
        /// <param name="useWindowsFix">
        ///   A <see cref="bool" /> indicating whether the image is drawn in a special way to fix problems that occur when
        ///   Windows applies tiled images for extended desktops. Set to <c>true</c> if you are planning to apply the generated
        ///   image on the Windows Desktop.
        /// </param>
        /// <returns>
        ///   A <see cref="Image" /> instance containing drawn the multiscreen wallpaper image.
        /// </returns>
        /// <exception cref="ArgumentException">
        ///   <paramref name="wallpapers" /> a <c>null</c> item.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   <paramref name="wallpapers" /> is empty.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="wallpapers" /> is <c>null</c>.
        /// </exception>
        /// <exception cref="FileNotFoundException">
        ///   The image file where on of the <see cref="Wallpaper" /> objects refers to could not be found.
        /// </exception>
        protected Image CreateMultiscreenFromMultipleInternal(IList <Wallpaper> wallpapers, float scaleFactor, bool useWindowsFix)
        {
            if (wallpapers == null)
            {
                throw new ArgumentNullException();
            }
            if (wallpapers.Count == 0)
            {
                throw new ArgumentException();
            }
            if (wallpapers.Contains(null))
            {
                throw new ArgumentException();
            }

            Rectangle fullScreenBounds = WallpaperBuilderBase.FullScreenBounds;
            int       screenCount      = Screen.AllScreens.Length;

            Bitmap wallpaperImage = new Bitmap((int)(fullScreenBounds.Width * scaleFactor), (int)(fullScreenBounds.Height * scaleFactor));

            using (Graphics graphics = Graphics.FromImage(wallpaperImage)) {
                Graphics destinationGraphics = graphics;
                Bitmap   preWallpaperImage   = null;

                try {
                    // If the fullscreenbounds rectangle has a negative x or y values, we normalize them by using 0,0 as origin and adding
                    // the difference to each drawn wallpaper later.
                    int xOriginAdd;
                    if (fullScreenBounds.X < 0)
                    {
                        xOriginAdd = Math.Abs(WallpaperBuilderBase.FullScreenBounds.X);
                    }
                    else
                    {
                        xOriginAdd = 0;
                    }

                    int yOriginAdd;
                    if (fullScreenBounds.Y < 0)
                    {
                        yOriginAdd = Math.Abs(WallpaperBuilderBase.FullScreenBounds.Y);
                    }
                    else
                    {
                        yOriginAdd = 0;
                    }

                    // Check if we have to redraw the end-wallpaper to fix it for Windows' strange way of applyment.
                    bool requiresWindowsFix = ((useWindowsFix) && ((fullScreenBounds.Left < 0) || (fullScreenBounds.Top < 0)));

                    if (requiresWindowsFix)
                    {
                        // We have to redraw it, we need another temporary image and draw on this one instead.
                        preWallpaperImage   = new Bitmap(wallpaperImage.Width, wallpaperImage.Height);
                        destinationGraphics = Graphics.FromImage(preWallpaperImage);
                    }

                    // Draw the full wallpaper.
                    destinationGraphics.ScaleTransform(scaleFactor, scaleFactor);

                    for (int i = 0; i < screenCount; i++)
                    {
                        Rectangle screenBounds = this.ScreensSettings[i].BoundsWithMargin;
                        screenBounds.X += xOriginAdd;
                        screenBounds.Y += yOriginAdd;

                        destinationGraphics.SetClip(screenBounds, CombineMode.Replace);
                        WallpaperBuilderBase.DrawWallpaper(destinationGraphics, screenBounds, wallpapers[i], wallpapers[i].Placement);
                        WallpaperBuilderBase.DrawOverlayTexts(destinationGraphics, screenBounds, wallpapers, this.ScreensSettings[i].TextOverlays);
                        destinationGraphics.ResetClip();
                    }

                    if (requiresWindowsFix)
                    {
                        // Now redraw the wallpaper but fixed.
                        WallpaperBuilderBase.DrawFullWallpaperFixed(graphics, preWallpaperImage);
                    }
                } finally {
                    destinationGraphics.Dispose();
                    preWallpaperImage?.Dispose();
                }
            }

            return(wallpaperImage);
        }
Example #2
0
        /// <summary>
        ///   Creates a multiscreen wallpaper from one <see cref="Wallpaper" /> object (from one image).
        /// </summary>
        /// <inheritdoc cref="CreateMultiscreenFromMultipleInternal" select='remarks|param|returns' />
        /// <param name="multiscreenWallpaper">
        ///   The <see cref="Wallpaper" /> object to use.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="multiscreenWallpaper" /> is <c>null</c>.
        /// </exception>
        /// <exception cref="FileNotFoundException">
        ///   The image file where the <paramref name="multiscreenWallpaper" /> object refers to could not be found.
        /// </exception>
        /// <seealso cref="Wallpaper">Wallpaper Class</seealso>
        public Image CreateMultiscreenFromSingle(Wallpaper multiscreenWallpaper, float scaleFactor, bool useWindowsFix)
        {
            if (multiscreenWallpaper == null)
            {
                throw new ArgumentNullException();
            }

            Rectangle fullScreenBounds = WallpaperBuilderBase.FullScreenBounds;
            Bitmap    wallpaperImage   = new Bitmap((int)(fullScreenBounds.Width * scaleFactor), (int)(fullScreenBounds.Height * scaleFactor));

            using (Graphics graphics = Graphics.FromImage(wallpaperImage)) {
                Graphics destinationGraphics = graphics;
                Bitmap   preWallpaperImage   = null;

                try {
                    // If the fullscreenbounds rectangle has a negative x or y values, we normalize them by using 0,0 as origin and adding
                    // the difference to each drawn wallpaper later.
                    int xOriginAdd;
                    if (fullScreenBounds.X < 0)
                    {
                        xOriginAdd = Math.Abs(WallpaperBuilderBase.FullScreenBounds.X);
                    }
                    else
                    {
                        xOriginAdd = 0;
                    }

                    int yOriginAdd;
                    if (fullScreenBounds.Y < 0)
                    {
                        yOriginAdd = Math.Abs(WallpaperBuilderBase.FullScreenBounds.Y);
                    }
                    else
                    {
                        yOriginAdd = 0;
                    }

                    // Check if we have to redraw the end-wallpaper to fix it for Windows.
                    bool requiresWindowsFix = ((useWindowsFix) && ((fullScreenBounds.Left < 0) || (fullScreenBounds.Top < 0)));

                    if (requiresWindowsFix)
                    {
                        // We have to redraw it, we need another temporary image and draw on this one instead.
                        preWallpaperImage   = new Bitmap(wallpaperImage.Width, wallpaperImage.Height);
                        destinationGraphics = Graphics.FromImage(preWallpaperImage);
                    }

                    destinationGraphics.ScaleTransform(scaleFactor, scaleFactor);

                    // The rectangle of the multiscreen wallpaper should span across all screens except the ones which should display
                    // a statical wallpaper.
                    Rectangle?multiscreenWallpaperRect = null;

                    for (int i = 0; i < this.ScreensSettings.Count; i++)
                    {
                        if (this.ScreensSettings[i].CycleRandomly || !this.ScreensSettings[i].StaticWallpaper.EvaluateCycleConditions())
                        {
                            if (multiscreenWallpaperRect == null)
                            {
                                multiscreenWallpaperRect = this.ScreensSettings[i].BoundsWithMargin;
                            }
                            else
                            {
                                multiscreenWallpaperRect = Rectangle.Union(multiscreenWallpaperRect.Value, this.ScreensSettings[i].BoundsWithMargin);
                            }
                        }
                    }

                    // null would mean that all screens should display static wallpapers.
                    if (multiscreenWallpaperRect != null)
                    {
                        Rectangle multiscreenWallpaperRectValue = multiscreenWallpaperRect.Value;
                        multiscreenWallpaperRectValue.X += xOriginAdd;
                        multiscreenWallpaperRectValue.Y += yOriginAdd;

                        destinationGraphics.SetClip(multiscreenWallpaperRectValue);
                        WallpaperBuilderBase.DrawWallpaper(destinationGraphics, multiscreenWallpaperRectValue, multiscreenWallpaper, multiscreenWallpaper.Placement);
                        destinationGraphics.ResetClip();
                    }

                    // Draw or overdraw all static wallpapers and draw the Overlay Texts for all screens.
                    for (int i = 0; i < this.ScreensSettings.Count; i++)
                    {
                        destinationGraphics.SetClip(this.ScreensSettings[i].BoundsWithMargin);

                        if (!this.ScreensSettings[i].CycleRandomly && this.ScreensSettings[i].StaticWallpaper.EvaluateCycleConditions())
                        {
                            WallpaperBuilderBase.DrawWallpaper(
                                destinationGraphics,
                                this.ScreensSettings[i].BoundsWithMargin,
                                this.ScreensSettings[i].StaticWallpaper,
                                this.ScreensSettings[i].StaticWallpaper.Placement);
                        }

                        WallpaperBuilderBase.DrawOverlayTexts(
                            destinationGraphics,
                            this.ScreensSettings[i].BoundsWithMargin,
                            new[] { multiscreenWallpaper },
                            this.ScreensSettings[i].TextOverlays);
                        destinationGraphics.ResetClip();
                    }

                    if (requiresWindowsFix)
                    {
                        // Now redraw the wallpaper but fixed.
                        WallpaperBuilderBase.DrawFullWallpaperFixed(graphics, preWallpaperImage);
                    }
                } finally {
                    destinationGraphics.Dispose();
                    preWallpaperImage?.Dispose();
                }
            }

            return(wallpaperImage);
        }