private static ImageSource caricaMascheraDaCorrezioneXml(string correzioneXml) { ImageSource imageSource = caricaImmagineDefault(); CorrezioniList correzioni = SerializzaUtil.stringToObject <CorrezioniList>((String)correzioneXml); ImmagineWic immagineMaschera = null; Mascheratura mascheratura = null; if (correzioni != null && correzioni.Contains(typeof(Mascheratura))) { mascheratura = (Mascheratura)correzioni.FirstOrDefault(c => c is Mascheratura); } if (correzioni != null && correzioni.Contains(typeof(MascheraturaOrientabile))) { MascheraturaOrientabile mo = (MascheraturaOrientabile)correzioni.FirstOrDefault(c => c is MascheraturaOrientabile); mascheratura = mo.mascheraturaH ?? mo.mascheraturaV; } if (mascheratura != null) { immagineMaschera = new ImmagineWic(Path.Combine(PathUtil.getCartellaMaschera(FiltroMask.MskSingole), mascheratura.nome)); } if (immagineMaschera != null) { imageSource = ((ImmagineWic)immagineMaschera).bitmapSource as ImageSource; } return(imageSource); }
/// <summary> /// Prendo la foto pulita e applico tutte le correzioni. /// Serve per il fotoritocco. /// Faccio tutto in un unico colpo per essere più efficiente. /// </summary> /// <param name="fotografia"></param> /// <param name="cosaRicalcolo"></param> public IImmagine applicaCorrezioni(IImmagine partenza, CorrezioniList correzioni, IdrataTarget cosaRicalcolo) { IImmagine modificata = partenza; // Ci sono alcune correzioni che sono più "complicate" e non posso trattarle in modo singolo, // ma devo gestire nell'insieme in modo efficiente. // In questo caso devo cambiare strategia. bool complicato = false; if (correzioni.SingleOrDefault(c => c is Imaging.Correzioni.Mascheratura) != null || correzioni.SingleOrDefault(c => c is Imaging.Correzioni.MascheraturaOrientabile) != null || correzioni.SingleOrDefault(c => c is Ruota && ((Ruota)c).isAngoloRetto == false) != null || correzioni.SingleOrDefault(c => c is Trasla) != null || correzioni.SingleOrDefault(c => c is Zoom) != null) { complicato = true; } if (complicato) { modificata = rigeneraImmagineConCorrezioniComplicate(partenza, correzioni, cosaRicalcolo); } else { // le correzioni sono tutte applicabili singolarmente. Non necessito di ricalcolo foreach (Correzione correzione in correzioni) { modificata = applicaCorrezione(modificata, correzione); } } return(modificata); }
/// <summary> /// Prendo le correzioni xml di una foto, /// e le converto nei rispettivi "Effetti" e/o "Trasformazioni" /// </summary> /// <typeparam name="T">Può essere un ShaderEffect oppure un Transform</typeparam> /// <param name="fotografia"></param> /// <returns> /// Se ho delle correzioni, allora ritorno La lista degli oggetti trasformati. <br/> /// Se invece non ho correzioni, allora ritorno null. /// </returns> public IList <T> converteCorrezioni <T>(CorrezioniList correzioni) { if (correzioni == null) { return(null); } // ok ho qualcosa da fare. Istanzio la lista da ritornare IList <T> convertiti = new List <T>(); foreach (Correzione correzione in correzioni) { Correttore correttore = gestoreImmaginiSrv.getCorrettore(correzione); if (correttore.CanConvertTo(typeof(T))) { convertiti.Add((T)correttore.ConvertTo(correzione, typeof(T))); } else { // non do errore, perché è la prassi che venga chiamato questo metodo per estrarre soltanto i tipi gestiti // _giornale.Error( "Impossibile convertire " + typeof( T ) + " in una correzione" ); } } return(convertiti); }
public CorrezioniList converteInCorrezioni(IEnumerable <Object> effetti) { if (effetti == null) { return(null); } CorrezioniList correzioni = new CorrezioniList(); foreach (var effettoTrasformazione in effetti) { Correttore correttore = this.getCorrettore(effettoTrasformazione); if (correttore == null) { continue; } if (correttore.CanConvertFrom(effettoTrasformazione.GetType())) { correzioni.Add((Correzione)correttore.ConvertFrom(effettoTrasformazione)); } } return(correzioni); }
public void addLogo(Fotografia fotografia, Logo logo, bool salvare) { if (logo == null) { // Rimuovo il logo dalle correzioni // Deserializzo la stringa con le eventuali correzioni attuali if (fotografia.correzioniXml != null) { CorrezioniList correzioni = SerializzaUtil.stringToObject <CorrezioniList>(fotografia.correzioniXml); foreach (Correzione c in correzioni) { if (c is Logo) { correzioni.Remove(c); break; } } // Ora serializzo di nuovo fotografia.correzioniXml = SerializzaUtil.objectToString(correzioni); } } else { // Siccome ho reso il logo sommabile, questa operazione in realtà non aggiunge ma sostituisce. addCorrezione(fotografia, logo, salvare); } // Ricalcolo il provino giusto per poterlo visualizzare AiutanteFoto.creaProvinoFoto(fotografia); }
public IList <T> converteCorrezioni <T>(Fotografia fotografia) { if (fotografia.correzioniXml == null) { return(null); } CorrezioniList correzioni = SerializzaUtil.stringToObject <CorrezioniList>(fotografia.correzioniXml); return(converteCorrezioni <T>(correzioni)); }
private Mascheratura estraiMascheratura(AzioneAuto azioneAuto) { if (azioneAuto.correzioniXml == null) { return(null); } CorrezioniList correzioniList = SerializzaUtil.stringToObject <CorrezioniList>(azioneAuto.correzioniXml); if (correzioniList == null || correzioniList.Count < 1) { return(null); } return((Mascheratura)correzioniList.FirstOrDefault(c => c is Mascheratura)); }
public static bool determinaSeComposizione(string correzioniXml) { bool composizione = false; CorrezioniList correzioniList = null; MascheraturaOrientabile mascheraturaOrientabile = null; // Controllo che l'azione corrente contenga una mascheratura orientabile correzioniList = SerializzaUtil.stringToObject <CorrezioniList>(correzioniXml); if (correzioniList != null && correzioniList.Count > 0) { mascheraturaOrientabile = (MascheraturaOrientabile)correzioniList.SingleOrDefault(mo => mo is MascheraturaOrientabile); composizione = (mascheraturaOrientabile != null); } return(composizione); }
public void objectToStringTest() { CorrezioniList lista = new CorrezioniList(); lista.Add(new Ruota() { gradi = 35 }); lista.Add(new BiancoNero()); lista.Add(new Ruota() { gradi = 50 }); string ris = SerializzaUtil.objectToString(lista, typeof(CorrezioniList)); object oo = SerializzaUtil.stringToObject(ris, typeof(CorrezioniList)); }
public void removeCorrezione(Fotografia foto, Type quale) { // Se non ho correzioni è impossibile che ne voglio rimuovere una if (foto.correzioniXml == null) { return; } // Deserializzo la stringa con le eventuali correzioni attuali CorrezioniList correzioni = SerializzaUtil.stringToObject <CorrezioniList>(foto.correzioniXml); bool rimossa = false; foreach (Correzione cor in correzioni) { if (cor.GetType().Equals(quale)) { correzioni.Remove(cor); rimossa = true; break; } } if (!rimossa) { return; } // Ora serializzo di nuovo in stringa tutte le correzioni if (correzioni.Count > 0) { foto.correzioniXml = SerializzaUtil.objectToString(correzioni); } else { foto.correzioniXml = null; } AiutanteFoto.creaProvinoFoto(foto); }
/// <summary> /// Aggiungo una correzione ad una lista di correzione. /// Se la correzione esiste già, gestisco eventuale somma, oppure rimozione in caso che sia inutile (ininfluente) /// </summary> /// <param name="correzioni"></param> /// <param name="correzioneNuova"></param> public void addCorrezione(ref CorrezioniList correzioni, Correzione correzioneNuova) { // Alcune correzioni, non devono andare sempre in aggiunta, ma possono sommarsi l'un l'altra. // Per esempio la rotazione. Se ruoto 90° poi altri 90, l'effetto finale è quello di avere una sola da 180° Correzione daSost = null; Correzione vecchia = null; foreach (Correzione c in correzioni) { if (c.isSommabile(correzioneNuova)) { vecchia = c; daSost = c.somma(correzioneNuova); break; } } if (daSost != null) { // Sostituisco la correzione con quella ricalcolata if (daSost.isInutile) { correzioni.Remove(vecchia); } else { correzioni.sostituire(vecchia, daSost); } } else { // Aggiungo in fondo (se la correzione è inutile, allora non aggiungo nulla) if (!correzioneNuova.isInutile) { correzioni.Add(correzioneNuova); } } }
/// <summary> /// Se una azione automatica contiene una mascheratura orientabile (quindi doppia) /// posso disassociarla e creare una nuova azione /// </summary> void disassociareMascheratura() { CorrezioniList correzioniList = null; AzioneAuto azioneAuto = azioneAutomaticaSelezionata; MascheraturaOrientabile mascheraturaOrientabile = null; // Controllo che l'azione corrente contenga una mascheratura orientabile if (azioneAuto.correzioniXml != null) { correzioniList = SerializzaUtil.stringToObject <CorrezioniList>(azioneAuto.correzioniXml); if (correzioniList != null && correzioniList.Count > 0) { mascheraturaOrientabile = (MascheraturaOrientabile)correzioniList.SingleOrDefault(mo => mo is MascheraturaOrientabile); } } if (mascheraturaOrientabile == null) { dialogProvider.ShowError("L'azione selezionata non contiene una <MascheraturaOrientabile>.\nSolo queste si possono separare!", "Azione non separabile", null); return; } // ok procedo a separare le cornici // Sostituisco la correzione nella lista, cercando di mettere quella nuova nella stessa posizione Mascheratura masH = mascheraturaOrientabile.mascheraturaH; Mascheratura masV = mascheraturaOrientabile.mascheraturaV; // Elimino la mascheratura doppia ... correzioniList.Remove(mascheraturaOrientabile); // aggiungo solo la mascheratura Orizzontale correzioniList.Insert(0, masV); // Aggiorno l'entità sul db OrmUtil.forseAttacca <AzioneAuto>(ref azioneAuto); azioneAuto.correzioniXml = SerializzaUtil.objectToString(correzioniList); // Ora creo l'altra azione CorrezioniList correzioniList2 = new CorrezioniList(); correzioniList2.Add(masH); AzioneAuto azioneV = new AzioneAuto { id = Guid.NewGuid(), attivo = true, nome = "Separata", correzioniXml = SerializzaUtil.objectToString(correzioniList2) }; UnitOfWorkScope.currentDbContext.AzioniAutomatiche.Add(azioneV); // Ora aggiungo anche alla collezione visiva azioniAutomatiche.Add(azioneV); deselezionareTutto(); // Purtroppo non si aggiornano le icone di overlay. devo ricaricare. App.Current.Dispatcher.BeginInvoke(new Action(() => { rileggereAzioniAutomaticheCommand.Execute(null); } )); }
void forseAssociareMaschere() { if (!modalitaAssociazione) { return; } // Per poter iniziare l'associazione, ocorre che la riga selezionata, contenga una mascheratura Mascheratura mascheratura2 = estraiMascheratura(azioneAutomaticaSelezionata); if (mascheratura2 == null) { dialogProvider.ShowError("L'azione selezionata non contiene Mascheratura", "Azioni non associate", null); return; } // Dalla prima azione, estraggo la mascheratura, perché devo controllare che sia di Orientamento opposto alla prima che ho fissato. CorrezioniList correzioni1 = SerializzaUtil.stringToObject <CorrezioniList>(azioneAutoAssociare1.correzioniXml); Mascheratura mascheratura1 = (Mascheratura)correzioni1.ToList <Correzione>().FirstOrDefault(c => c is Mascheratura); var ratio1 = mascheratura1.width / mascheratura1.height; var ratio2 = mascheratura2.width / mascheratura2.height; if ((ratio1 < 1 && ratio2 < 1) || (ratio1 > 1 && ratio2 > 1)) { dialogProvider.ShowError("Le maschere devono ossere di diverso orientamento.\nUna orizzontale ed una verticale!", "Azioni non associate", null); return; } // Ok : adesso posso procedere alla associazione MascheraturaOrientabile mo = new MascheraturaOrientabile(); mo.mascheraturaH = (ratio1 < 1 ? mascheratura2 : mascheratura1); mo.mascheraturaV = (ratio1 < 1 ? mascheratura1 : mascheratura2); using (new UnitOfWorkScope()) { // Sostituisco la correzione nella lista, cercando di mettere quella nuova nella stessa posizione int pos = correzioni1.IndexOf(mascheratura1); correzioni1.RemoveAt(pos); correzioni1.Insert(pos, mo); // Rimuovo l'azione2 dalla collezione a video AzioneAuto azioneDacanc = azioneAutomaticaSelezionata; azioniAutomatiche.Remove(azioneDacanc); // Ora vado ad aggiornare l'azione1 con le correzioni nuove AzioneAuto azione = azioneAutoAssociare1; OrmUtil.forseAttacca <AzioneAuto>(ref azione); azioneAutoAssociare1.correzioniXml = SerializzaUtil.objectToString(correzioni1); // Elimino dal db la azione2 OrmUtil.forseAttacca <AzioneAuto>(ref azioneDacanc); // Rimuovo l'azione dal database UnitOfWorkScope.currentDbContext.AzioniAutomatiche.Remove(azioneDacanc); UnitOfWorkScope.currentDbContext.SaveChanges(); // Torno in modalità normale modalitaAssociazione = false; } // Purtroppo non si aggiornano le icone di overlay. devo ricaricare. App.Current.Dispatcher.BeginInvoke(new Action(() => { rileggereAzioniAutomaticheCommand.Execute(null); } )); }
/// <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); }
/// <summary> /// Aggiungo una correzione a quelle già eventualmente presenti sulla foto. /// Se la correzione esiste già, gestisco eventuale somma, oppure rimozione in caso che sia inutile (ininfluente) /// </summary> /// <param name="fotografia">la foto</param> /// <param name="correzione">la correzione da aggiungere</param> public void addCorrezione(Fotografia fotografia, Correzione correzioneNuova, bool salvare) { CorrezioniList correzioni; // Deserializzo la stringa con le eventuali correzioni attuali if (fotografia.correzioniXml == null) { correzioni = new CorrezioniList(); } else { correzioni = SerializzaUtil.stringToObject <CorrezioniList>(fotografia.correzioniXml); } // Alcune correzioni, non devono andare sempre in aggiunta, ma possono sommarsi l'un l'altra. // Per esempio la rotazione. Se ruoto 90° poi altri 90, l'effetto finale è quello di avere una sola da 180° Correzione daSost = null; Correzione vecchia = null; foreach (Correzione c in correzioni) { if (c.isSommabile(correzioneNuova)) { vecchia = c; daSost = c.somma(correzioneNuova); break; } } if (daSost != null) { // Sostituisco la correzione con quella ricalcolata if (daSost.isInutile) { correzioni.Remove(vecchia); } else { correzioni.sostituire(vecchia, daSost); } } else { // Aggiungo in fondo (se la correzione è inutile, allora non aggiungo nulla) if (!correzioneNuova.isInutile) { correzioni.Add(correzioneNuova); } } // Ora serializzo di nuovo in stringa tutte le correzioni fotografia.correzioniXml = SerializzaUtil.objectToString(correzioni); if (salvare) { fotografieRepositorySrv.saveChanges(); // Persisto nel db le modifiche AiutanteFoto.creaProvinoFoto(fotografia); // Devo informare tutti che questa foto è cambiata FotoModificateMsg msg = new FotoModificateMsg(this, fotografia); pubblicaMessaggio(msg); } }
/// <summary> /// Creo il Provino, e/o la Risultante di una foto e scrivo l'immagine su disco nel file indicato /// </summary> /// <param name="nomeFileSorgente">E' il nome del file della foto vera, grande</param> /// <param name="foto"></param> private static void creaCacheFotoSuDisco(Fotografia foto, IdrataTarget quale, string nomeFileOriginale) { _giornale.Debug("Creo provino foto n." + foto.numero + " target=" + quale); Debug.Assert(quale == IdrataTarget.Provino || quale == IdrataTarget.Risultante); IGestoreImmagineSrv gis = LumenApplication.Instance.getServizioAvviato <IGestoreImmagineSrv>(); IFotoRitoccoSrv fr = LumenApplication.Instance.getServizioAvviato <IFotoRitoccoSrv>(); // Carico l'immagine grande originale (solo la prima volta) bool caricataOrig = false; if (foto.imgOrig == null) { _giornale.Debug("carico immagine originale da disco: " + nomeFileOriginale); foto.imgOrig = gis.load(nomeFileOriginale); caricataOrig = true; } // carico eventuali correzioni CorrezioniList correzioni = null; if (foto.correzioniXml != null) { try { correzioni = SerializzaUtil.stringToObject <CorrezioniList>(foto.correzioniXml); } catch (Exception ee) { // Se ci fossero inciampi con le correzioni, preferisco perderle che far saltare tutto. // Non dovrebbe mai capitare. _giornale.Error("Deserializza correzioni foto = " + foto.id, ee); } } // Se devo crere il provino ma la foto contiene la correzione di Zoom, // devo passare dalla foto grande, altrimenti perde di qualità bool devoPassareDallaGrande = false; if (quale == IdrataTarget.Risultante) { devoPassareDallaGrande = true; } if (correzioni != null && correzioni.Contains(typeof(Zoom))) { devoPassareDallaGrande = true; } // Se richiesto nella configurazione, scrivo direttamente sul provino le righe tratteggiate di rispetto area stampabile bool aggiungiCorrezioneAreaRispetto = false; if (Configurazione.UserConfigLumen.imprimereAreaDiRispetto) { if (quale == IdrataTarget.Provino) { if (correzioni == null) { correzioni = new CorrezioniList(); } if (!correzioni.Contains(typeof(AreaRispetto))) { aggiungiCorrezioneAreaRispetto = true; } } } // Cancello il file Risultante da disco perchè tanto sta per cambiare. IImmagine immagineDestinazione = null; foto.imgRisultante = null; string nomeFileRisultante = PathUtil.nomeCompletoFile(foto, IdrataTarget.Risultante); if (File.Exists(nomeFileRisultante)) { File.Delete(nomeFileRisultante); } // Eventuale creazione delle cartelle di destinazione (potrebbero non esistere) PathUtil.creaCartellaProvini(foto); PathUtil.creaCartellaRisultanti(foto); // OK partiamo! if (devoPassareDallaGrande) { immagineDestinazione = (IImmagine)foto.imgOrig.Clone(); // creo un duplicato della Originale per poi lavorarci } else { immagineDestinazione = gis.creaProvino(foto.imgOrig); // creo una immagine più piccola } // applico eventuali correzioni if (correzioni != null) { IdrataTarget tempQuale = quale; if (devoPassareDallaGrande && quale == IdrataTarget.Provino) { tempQuale = IdrataTarget.Risultante; } if (aggiungiCorrezioneAreaRispetto && tempQuale == IdrataTarget.Provino) { correzioni.Add(areaRispetto); } immagineDestinazione = fr.applicaCorrezioni(immagineDestinazione, correzioni, tempQuale); // NO : non funziona sempre bene. // Se sto facendo un provino che prevede lo zoom, devo passare dalla immagine grande, // quindi sono obbligato a ricalcolare la Risultante e quindi rimpicciolirla. // quindi per essere efficiente, salvo la Risultante che ho già pronta (cosi risparmio tempo dopo) if (devoPassareDallaGrande && quale == IdrataTarget.Provino) { gis.save(immagineDestinazione, nomeFileRisultante); foto.imgRisultante = immagineDestinazione; // Poi la ritaglio per fare il provino buono. immagineDestinazione = gis.creaProvino(immagineDestinazione); // Aggiungo l'area di rispetto al provino if (aggiungiCorrezioneAreaRispetto) { immagineDestinazione = fr.applicaCorrezione(immagineDestinazione, areaRispetto); } } } // Salvo su disco l'immagine di destinazione string nomeFileDest = PathUtil.nomeCompletoFile(foto, quale); gis.save(immagineDestinazione, nomeFileDest); _giornale.Debug("Ho ricreato il file immagine di cache: " + nomeFileDest); // Eventualmente chiudo l'immagine grande se l'avevo aperta io. // Il provino, invece lo lascio aperto (non so se mi causerà problemi di memoria) if (caricataOrig) { AiutanteFoto.disposeImmagini(foto, IdrataTarget.Originale); } // Modifico la foto che mi è stata passata. if (quale == IdrataTarget.Provino) { foto.imgProvino = immagineDestinazione; } if (quale == IdrataTarget.Risultante) { foto.imgRisultante = immagineDestinazione; } }