public override object Clone() { if (this.bitmapSource == null) { throw new ObjectDisposedException("immagineWic"); } // Per motivi di thread multipli non posso chiamare il clone della mia sorgente, ma ne devo creare una nuova // TODO purtroppo queste operazioni mi fanno sciupare un sacco di memoria RAM inutile. // Devo assolutamente risolvere in altro modo. WriteableBitmap wb = new WriteableBitmap(this.bitmapSource); ImmagineWic immagine = new ImmagineWic(wb); return(immagine); // Se la bitmap è nulla mi sta bene che si spacchi. In tal caso correggere il programma chiamante. }
/// <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); }