/// <summary> /// Devo gestire le correzioni complicate /// </summary> /// <param name="immaginePartenza"></param> /// <param name="correzioni"></param> /// <returns></returns> private IImmagine rigeneraImmagineConCorrezioniComplicate(IImmagine immaginePartenza, CorrezioniList correzioni, IdrataTarget qualeTarget) { double wwDest = 0, hhDest = 0; BitmapSource bmpFoto = null; // Questa è la foto BitmapSource bmpMaschera = null; // Questa è la maschera (eventuale) bmpFoto = ((ImmagineWic)immaginePartenza).bitmapSource; // ::: Per prima cosa calcolo la dimensione che deve avere l'immagine di uscita (il canvas) // Verifico quindi se c'è una maschera. In tal caso comanda lei Imaging.Correzioni.Mascheratura mascheratura = (Imaging.Correzioni.Mascheratura)correzioni.FirstOrDefault(c => c is Imaging.Correzioni.Mascheratura); // La mascheratura potrebbe essere anche indicata come orientabile if (mascheratura == null) { Imaging.Correzioni.MascheraturaOrientabile mascheraturaOrientabile = (Imaging.Correzioni.MascheraturaOrientabile)correzioni.FirstOrDefault(c => c is Imaging.Correzioni.MascheraturaOrientabile); if (mascheraturaOrientabile != null) { // Ora estraggo la mascheratura giusta per questa foto if (immaginePartenza.orientamento == Orientamento.Verticale) { mascheratura = mascheraturaOrientabile.mascheraturaV; } if (immaginePartenza.orientamento == Orientamento.Orizzontale) { mascheratura = mascheraturaOrientabile.mascheraturaH; } } } // // Ora che ho scoperto se esiste una mascheratura, la applico // if (mascheratura != null) { ImmagineWic immagineMaschera = new ImmagineWic(Path.Combine(getCartellaMaschera(FiltroMask.MskSingole), mascheratura.nome)); bmpMaschera = immagineMaschera.bitmapSource; // Carico la maschera per avere le dimensioni reali definitive if (qualeTarget == IdrataTarget.Provino) { IImmagine imgMascheraPiccola = gestoreImmaginiSrv.creaProvino(immagineMaschera); bmpMaschera = ((ImmagineWic)imgMascheraPiccola).bitmapSource; } wwDest = bmpMaschera.PixelWidth; hhDest = bmpMaschera.PixelHeight; } else { // Cerco di intercettare un eventuale rotazione del quadro (non della foto) Zoom zzz = (Zoom)correzioni.FirstOrDefault(c => c is Zoom); bool rovesciare = zzz != null ? zzz.quadroRuotato : false; if (rovesciare) { wwDest = bmpFoto.PixelHeight; hhDest = bmpFoto.PixelWidth; } else { wwDest = bmpFoto.PixelWidth; hhDest = bmpFoto.PixelHeight; } } // ::: Il canvas Canvas canvas = new Canvas(); canvas.Background = new SolidColorBrush(Colors.White); canvas.Width = wwDest; canvas.Height = hhDest; canvas.HorizontalAlignment = HorizontalAlignment.Left; canvas.VerticalAlignment = VerticalAlignment.Top; #region Correzioni // ::: Gestisco le correzioni TransformGroup traGroup = new TransformGroup(); IList <ShaderEffect> effetti = null; // bool quadroRuotato = false; foreach (Correzione correzione in correzioni) { Correttore correttore = gestoreImmaginiSrv.getCorrettore(correzione); if (correttore.CanConvertTo(typeof(Transform))) { // ::: Trasformazioni Transform trasformazione = (Transform)correttore.ConvertTo(correzione, typeof(Transform)); // La trasformazione di spostamento, (Trasla) fa una eccezione perché dipende dalla grandezza del target. // Devo sistemarla al volo if (trasformazione is TranslateTransform) { TranslateTransform tt = (TranslateTransform)trasformazione; // TODO riproporzionare TranslateTransform tt2 = new TranslateTransform(); // Devo riproporzionare X e Y alla dimensione giusta finale. // posx:300=x:finalW -> x = posx * finalW / 300 tt2.X = ((TranslateTransform)tt).X * canvas.Width / ((Trasla)correzione).rifW; tt2.Y = ((TranslateTransform)tt).Y * canvas.Height / ((Trasla)correzione).rifH; traGroup.Children.Add(tt2); } else { traGroup.Children.Add(trasformazione); } } else if (correttore.CanConvertTo(typeof(ShaderEffectBase))) { // ::: Effetti li sommo poi li faccio tutti in una volta per essere più veloce if (effetti == null) { effetti = new List <ShaderEffect>(); } effetti.Add((ShaderEffect)correttore.ConvertTo(correzione, typeof(ShaderEffectBase))); } } #endregion Correzioni if (effetti != null && effetti.Count > 0) { bmpFoto = EffectsUtil.RenderImageWithEffectsToBitmap(bmpFoto, effetti); } // ::: La foto Image fotona = new Image(); fotona.BeginInit(); fotona.Source = bmpFoto; // bmpFoto; fotona.Stretch = Stretch.Uniform; fotona.HorizontalAlignment = HorizontalAlignment.Center; fotona.VerticalAlignment = VerticalAlignment.Center; fotona.Width = wwDest; fotona.Height = hhDest; fotona.EndInit(); // Assegno tutte le trasformazioni if (traGroup != null && traGroup.Children.Count > 0) { fotona.RenderTransform = traGroup; fotona.RenderTransformOrigin = new Point(0.5, 0.5); // centrate } canvas.Children.Add(fotona); // ::: La Maschera - per concludere, aggiungo anche la maschera che deve ricoprire tutto. Image imageMaschera; if (bmpMaschera != null) { imageMaschera = new Image(); imageMaschera.BeginInit(); imageMaschera.Stretch = Stretch.Uniform; imageMaschera.HorizontalAlignment = HorizontalAlignment.Left; imageMaschera.VerticalAlignment = VerticalAlignment.Top; imageMaschera.Source = bmpMaschera; imageMaschera.Width = wwDest; imageMaschera.Height = hhDest; imageMaschera.EndInit(); canvas.Children.Add(imageMaschera); } // Devo "Arrangiare" il canvas altrimenti non ha dimensione (e la foto viene nera) var size = new Size(wwDest, hhDest); canvas.Measure(size); canvas.Arrange(new Rect(size)); IImmagine immagineMod = null; // Creo la bitmap di ritorno RenderTargetBitmap rtb = new RenderTargetBitmap((int)canvas.Width, (int)canvas.Height, 96d, 96d, PixelFormats.Pbgra32); rtb.Render(canvas); if (rtb.CanFreeze) { rtb.Freeze(); } immagineMod = new ImmagineWic(rtb); // Come penultima cosa, mi rimane da gestire le Scritte (in realtà una sola) foreach (var scritta in correzioni.OfType <Scritta>()) { Correttore correttore = gestoreImmaginiSrv.getCorrettore(scritta); immagineMod = correttore.applica(immagineMod, scritta); } // Per ultima cosa, mi rimane fuori un evenuale logo ... Logo correzioneLogo = (Logo)correzioni.FirstOrDefault(c => c is Logo); if (correzioneLogo != null) { Correttore correttore = gestoreImmaginiSrv.getCorrettore(correzioneLogo); immagineMod = correttore.applica(immagineMod, correzioneLogo); } // Questa forzatura anche se filosoficamente non è bella, ma mi serve per essere più veloce a creare le correzioni complesse sulla foto da stampare. // .. oppure una eventuale area di rispetto (solo sul provino) if (qualeTarget == IdrataTarget.Provino) { AreaRispetto correzioneAreaRispetto = (AreaRispetto)correzioni.FirstOrDefault(c => c is AreaRispetto); if (correzioneAreaRispetto != null) { Correttore correttore = gestoreImmaginiSrv.getCorrettore(correzioneAreaRispetto); immagineMod = correttore.applica(immagineMod, correzioneAreaRispetto); } } return(immagineMod); }
public override IImmagine applica(IImmagine immagineSorgente, Correzione correzione) { // Ricavo la bitmap sorgente BitmapSource bmpSorgente = ((ImmagineWic)immagineSorgente).bitmapSource; AreaRispetto areaRispetto = (AreaRispetto)correzione; CalcolatoreAreeRispetto.Geo imageGeo = new CalcolatoreAreeRispetto.Geo(); // Calcolo la fascia A imageGeo.w = immagineSorgente.ww; imageGeo.h = immagineSorgente.hh; Rect rettangoloA = CalcolatoreAreeRispetto.calcolaDimensioni(CalcolatoreAreeRispetto.Fascia.FasciaA, areaRispetto.ratio, imageGeo); CalcolatoreAreeRispetto.Bordi bordiA = CalcolatoreAreeRispetto.calcolcaLatiBordo(CalcolatoreAreeRispetto.Fascia.FasciaA, areaRispetto.ratio, imageGeo, imageGeo); // Calcolo la fascia B imageGeo.w = immagineSorgente.ww; imageGeo.h = immagineSorgente.hh; Rect rettangoloB = CalcolatoreAreeRispetto.calcolaDimensioni(CalcolatoreAreeRispetto.Fascia.FasciaB, areaRispetto.ratio, imageGeo); CalcolatoreAreeRispetto.Bordi bordiB = CalcolatoreAreeRispetto.calcolcaLatiBordo(CalcolatoreAreeRispetto.Fascia.FasciaB, areaRispetto.ratio, imageGeo, imageGeo); BitmapSource bmpFinale = null; if (areaRispetto.costringi) { int w = 0, h = 0; // Devo fare un resize che preservi il canale alpha (ovviamente l'immagine potrà risultare distorta, perché non devo preservare le proporzioni if (bordiA.right || bordiA.left || bordiB.right || bordiB.left) { // Taglio verticale: la foto è orizzontale w = immagineSorgente.ww - (int)rettangoloA.Width - (int)rettangoloB.Width; h = immagineSorgente.hh; } if (bordiA.top || bordiA.bottom || bordiB.top || bordiB.bottom) { // Tagli orizzontali: la foto è verticale h = immagineSorgente.hh - (int)rettangoloA.Height - (int)rettangoloB.Height; w = immagineSorgente.ww; } bmpFinale = ResizeCorrettore.Resize(bmpSorgente, w, h, (int)bmpSorgente.DpiX); } else { // Create a DrawingVisual/Context to render with DrawingVisual drawingVisual = new DrawingVisual(); Rect rect = new Rect(0, 0, immagineSorgente.ww, immagineSorgente.hh); RenderTargetBitmap renderTargetBitmap = null; Pen pennaRossa = new Pen(Brushes.Red, 2); pennaRossa.DashStyle = DashStyles.Dash; // tratteggio using (DrawingContext drawingContext = drawingVisual.RenderOpen()) { drawingContext.DrawImage(bmpSorgente, rect); // Prima linea di rispetto : calcolo i due punti Point p1, p2, p3, p4; calcolaPunti(bordiA, rettangoloA, out p1, out p2); calcolaPunti(bordiB, rettangoloB, out p3, out p4); // Disegno le due linee di rispetto drawingContext.DrawLine(pennaRossa, p1, p2); drawingContext.DrawLine(pennaRossa, p3, p4); } renderTargetBitmap = new RenderTargetBitmap((int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default); renderTargetBitmap.Render(drawingVisual); bmpFinale = renderTargetBitmap; } if (bmpFinale.CanFreeze) { bmpFinale.Freeze(); } return(new ImmagineWic(bmpFinale)); }
static AiutanteFoto() { float ratio = Convert.ToSingle(CoreUtil.evaluateExpression(Configurazione.UserConfigLumen.expRatioAreaDiRispetto)); areaRispetto = new AreaRispetto(ratio); }