public void OnNext(FotoModificateMsg fmMsg) { if (slideShow == null) { return; } foreach (Fotografia modificata in fmMsg.fotos) { int pos = slideShow.slides.IndexOf(modificata); if (pos > 0) { AiutanteFoto.disposeImmagini(slideShow.slides[pos], IdrataTarget.Provino); // Se la foto è stata modificata, allora mi copio le correzioni. slideShow.slides[pos].correzioniXml = modificata.correzioniXml; // Se ho a disposizione l'immagine del provino, me la copio, altrimenti me la rileggo da disco. if (modificata.imgProvino != null) { slideShow.slides[pos].imgProvino = (Digiphoto.Lumen.Imaging.IImmagine)modificata.imgProvino; } else { AiutanteFoto.idrataImmaginiFoto(slideShow.slides[pos], IdrataTarget.Provino, true); } } } }
private byte[] getImage(Guid fotografiaId, IdrataTarget quale) { byte[] bytes = null; using (new UnitOfWorkScope()) { var srv = LumenApplication.Instance.getServizioAvviato <IEntityRepositorySrv <Fotografia> >(); Fotografia fotografia = srv.getById(fotografiaId); string nomeFileImg; // Qui faccio una piccola miglioria: Se l'immagine risultante ha delle correzioni non ancora applicate, le applico adesso. if (quale == IdrataTarget.Risultante) { nomeFileImg = AiutanteFoto.idrataImmagineDaStampare(fotografia); } else { nomeFileImg = AiutanteFoto.idrataImmaginiFoto(fotografia, quale); } bytes = File.ReadAllBytes(nomeFileImg); AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Tutte); } return(bytes); }
/// <summary> /// Elimina tutte le Correzioni da una foto e quindi ricrea il provino /// </summary> public void tornaOriginale(Fotografia fotografia, bool salvare) { fotografia.correzioniXml = null; // Rimuovo anche eventuale file su disco string nomeFileRis = PathUtil.nomeCompletoRisultante(fotografia); if (File.Exists(nomeFileRis)) { File.Delete(nomeFileRis); } // Rilascio memoria AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Tutte); AiutanteFoto.creaProvinoFoto(fotografia); // Le due foto grandi le rilascio per non intasare la memoria qualora questo metodo è chiamato più volte AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Originale); AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Risultante); if (salvare) { Fotografia f = fotografia; fotografieRepositorySrv.update(ref f, true); fotografieRepositorySrv.saveChanges(); // Persisto nel db le modifiche // Devo informate tutti che questa foto è cambiata FotoModificateMsg msg = new FotoModificateMsg(this, fotografia); pubblicaMessaggio(msg); } }
/// <summary> /// Uso tutti try-catch perché è importante che io arrivi a fare la dispose del DbContext, /// altrimenti mi rimangono le entità tracciate. /// </summary> public void Dispose() { // Se ho delle fotografie caricate, rilascio le immagini if (carrello != null && carrello.righeCarrello != null) { foreach (RigaCarrello riga in carrello.righeCarrello) { try { AiutanteFoto.disposeImmagini(riga.fotografia); } catch (Exception) { } } } // Se il carrello è stato modificato nel db o aggiunto al db ma non ancora committato, allora devo "tornare indietro" if (carrello != null && isCarrelloTransient == false) { try { OrmUtil.rinuncioAlleModifiche(carrello, mioDbContext); } catch (Exception) { } carrello = null; } isCarrelloModificato = false; // Distruggo anche il contesto. In questo modo riparto pulito per il prossimo carrello, ma sopattutto devo rilasciare le entità che sono "tracciate" da questo context this.mioDbContext.Dispose(); this.mioDbContext = null; }
public void tornaOriginale(IEnumerable <Fotografia> fotografie, bool salvare) { foreach (Fotografia fotografia in fotografie) { fotografia.correzioniXml = null; // Rimuovo anche eventuale file su disco string nomeFileRis = PathUtil.nomeCompletoRisultante(fotografia); if (File.Exists(nomeFileRis)) { File.Delete(nomeFileRis); } // Rilascio memoria AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Tutte); if (salvare) { Fotografia f = fotografia; fotografieRepositorySrv.update(ref f, true); fotografieRepositorySrv.saveChanges(); // Persisto nel db le modifiche } } // Rifaccio tutti i provini in background provinare(fotografie); }
protected override void Dispose(bool disposing) { try { // Se il tread di copia è ancora vivo, lo uccido if (_threadIdrata != null) { if (_threadIdrata.IsAlive) { _threadIdrata.Abort(); } else { _threadIdrata.Join(); } } } finally { } try { if (this.fotografie != null) { foreach (Fotografia foto in this.fotografie) { AiutanteFoto.disposeImmagini(foto); } } } finally { } base.Dispose(disposing); }
void provinatore_ProgressChanged(object sender, ProgressChangedEventArgs e) { Fotografia foto = (Fotografia)e.UserState; bool esistevaRisultante = foto.imgRisultante != null; // Rilascio memoria AiutanteFoto.disposeImmagini(foto, IdrataTarget.Tutte); AiutanteFoto.creaProvinoFoto(foto); // Le due foto grandi le rilascio per non intasare la memoria qualora questo metodo è chiamato più volte AiutanteFoto.disposeImmagini(foto, IdrataTarget.Originale); AiutanteFoto.disposeImmagini(foto, IdrataTarget.Risultante); bool esisteRisultante = foto.imgRisultante != null; // Siccome è molto probabile che venga idratata l'immagine risultante e siccome sono in un loop, // non posso tenere in memoria tanta roba, altrimenti esplode if (esisteRisultante && !esistevaRisultante) { // Significa che l'ho idratata io in questo momento AiutanteFoto.disposeImmagini(foto, IdrataTarget.Risultante); } // Avviso tutti che questa foto è cambiata FotoModificateMsg msg = new FotoModificateMsg(this, foto); pubblicaMessaggio(msg); }
/// <summary> // azzero la gallery corrente e rilascio la memoria eventualmente utilizzata dalle foto /// </summary> private void svuotaGalleryCorrente() { if (fotografie != null) { foreach (Fotografia f in fotografie) { AiutanteFoto.disposeImmagini(f, IdrataTarget.Tutte); } FormuleMagiche.rilasciaMemoria(); } fotografie = null; }
/// <summary> /// Se ho delle foto visibili, rilascio la memoria delle foto più pesanti /// poi svuoto la lista /// </summary> void rilasciaEdAzzeraVisibili() { if (slidesVisibili != null) { // Devo rilasciare la memoria delle immagini pesanti precedenti prima di pulire foreach (var slideVisibile in slidesVisibili) { AiutanteFoto.disposeImmagini(slideVisibile, IdrataTarget.Risultante); AiutanteFoto.disposeImmagini(slideVisibile, IdrataTarget.Originale); } slidesVisibili.Clear(); } }
public void DisposeFotografia(Fotografia fotografia) { if (_fotografiaCorrente == null) { _fotografiaCorrente = fotografia; } if (_fotografiaCorrente != null && !_fotografiaCorrente.Equals(fotografia)) { AiutanteFoto.disposeImmagini(_fotografiaCorrente, IdrataTarget.Risultante); AiutanteFoto.disposeImmagini(_fotografiaCorrente, IdrataTarget.Originale); _fotografiaCorrente = fotografia; } }
/// <summary> /// Elimino e distruggo le foto sparse indicate /// </summary> /// <param name="fotosDaCanc"></param> public int elimina(IEnumerable <Fotografia> fotosDaCanc) { _possoChiudere = false; int conta = 0; _giornale.Info("E' stata richiesta la distruzione di " + fotosDaCanc.Count() + " fotografie. Iniizo eliminazione"); LumenEntities lumenEntities = UnitOfWorkScope.currentDbContext; foreach (Fotografia ff in fotosDaCanc) { Fotografia ff2 = ff; OrmUtil.forseAttacca <Fotografia>(ref ff2); AiutanteFoto.disposeImmagini(ff2); // Elimino la foto da disco seEsisteCancella(PathUtil.nomeCompletoRisultante(ff2)); seEsisteCancella(PathUtil.nomeCompletoProvino(ff2)); seEsisteCancella(PathUtil.nomeCompletoOrig(ff2)); // Poi dal database lumenEntities.Fotografie.Remove(ff2); _giornale.Debug("Eliminata Fotogarfia dal db: id=" + ff2.id + " num=" + ff2.numero); ++conta; } int test3 = lumenEntities.SaveChanges(); _giornale.Info("Eliminazione foto completata. Tot = " + conta); _giornale.Debug("la SaveChanges ha ritornato: " + test3); if (test3 > 0) { // Rilancio un messaggio in modo che tutta l'applicazione (e tutti i componenti) vengano notificati FotoEliminateMsg msg = new FotoEliminateMsg(this as IEliminaFotoVecchieSrv); msg.listaFotoEliminate = fotosDaCanc; pubblicaMessaggio(msg); } _possoChiudere = true; return(conta); }
public void OnNext(FotoEliminateMsg msg) { if (slideShow == null) { return; } foreach (Fotografia fotoEliminata in msg.listaFotoEliminate) { // Elimino dalla collezione delle foto quelle che non ci sono più int pos = slideShow.slides.IndexOf(fotoEliminata); if (pos > 0) { AiutanteFoto.disposeImmagini(slideShow.slides [pos], IdrataTarget.Tutte); slideShow.slides.Remove(fotoEliminata); } } }
/// <summary> /// Faccio qualche controllo preventivo. /// </summary> /// <param name="fotografia"></param> /// <param name="ruota"></param> public void autoRuotaSuOriginale(Fotografia fotografia, Ruota ruota) { if (fotografia.correzioniXml != null) { throw new LumenException("Sulla foto " + fotografia.numero + " esistono correzioni.\nImpossibile ruotare sull'originale.\nRimuovere prima le correzioni (torna originale)"); } if (!ruota.isAngoloRetto) { throw new ArgumentException("La rotazione sull'originale funziona solo con angoli retti"); } string nomeFileOrig = PathUtil.nomeCompletoOrig(fotografia); string estensione = Path.GetExtension(nomeFileOrig); if (fotografia.imgOrig == null) { AiutanteFoto.idrataImmaginiFoto(fotografia, IdrataTarget.Originale); } IImmagine imgRuotata = applicaCorrezione(fotografia.imgOrig, ruota); string nomeFileBackup = Path.ChangeExtension(nomeFileOrig, "BACKUP" + estensione); if (!File.Exists(nomeFileBackup)) { // Salvo per sicurezza il file originale File.Move(nomeFileOrig, nomeFileBackup); } fotografia.imgOrig = imgRuotata; gestoreImmaginiSrv.save(imgRuotata, nomeFileOrig); AiutanteFoto.creaProvinoFoto(fotografia); // Libero memoria. Lascio solo il provino AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Originale); AiutanteFoto.disposeImmagini(fotografia, IdrataTarget.Risultante); }
public void outOfMemoryImmagini() { const int quante = 1000; const int ogniTotPurga = 100; List <Fotografia> ff = cercaFotoQuasiasi(5); // Ricavo la memoria libera prima del test long memoryPrima = Process.GetCurrentProcess().WorkingSet64; for (int ii = 0; ii < quante; ii++) { foreach (Fotografia f in ff) { AiutanteFoto.idrataImmaginiFoto(f, IdrataTarget.Tutte); AiutanteFoto.disposeImmagini(f, IdrataTarget.Tutte); // ogni tot iterazioni, vado a liberare la memoria che inspiegabilmente non viene pulita. if ((ii % ogniTotPurga) == 0) { // ATTENZIONE: IMPORTANTE. // Se non metto questa formula magica, // il GC non pulisce la memoria occupata dalla bitmap (inspiegabilmente) FormuleMagiche.rilasciaMemoria(); } long memoryDurante = Process.GetCurrentProcess().WorkingSet64; long consumata = (memoryDurante - memoryPrima); // Se supero il massimo impostato, probabilmente il gc non sta pulendo. if (consumata > maxMem) { Assert.Fail("Probabilmente si sta consumando troppa memoria: diff(MB)=" + consumata / 1024); } } } }
public void clonaImmagineIncorniciata(Fotografia fotoOrig, string nomeFileImg) { FileInfo fileInfoSrc = new FileInfo(fotoOrig.nomeFile); string nomeOrig = fileInfoSrc.Name; string nomeFotoClone = ClonaImmaginiWorker.getNomeFileClone(fotoOrig); string nomeFileDest = Path.Combine(Config.Configurazione.cartellaRepositoryFoto, Path.GetDirectoryName(fotoOrig.nomeFile), nomeFotoClone); //Sposto la foto nella coartellaRepository e gli attribuisco il suo nome originale. File.Move(nomeFileImg, nomeFileDest); Fotografia fotoMsk = null; using (new UnitOfWorkScope(false)) { try { fotoMsk = new Fotografia(); fotoMsk.id = Guid.NewGuid(); fotoMsk.dataOraAcquisizione = fotoOrig.dataOraAcquisizione; Fotografo f = fotoOrig.fotografo; OrmUtil.forseAttacca <Fotografo>(ref f); fotoMsk.fotografo = f; if (fotoOrig.evento != null) { Evento e = fotoOrig.evento; OrmUtil.forseAttacca <Evento>(ref e); fotoMsk.evento = e; } fotoMsk.didascalia = fotoOrig.didascalia; fotoMsk.numero = fotoOrig.numero; // Le correzioni non devo duplicarle perché non sono tipiche della composizione finale, ma della foto originale. fotoMsk.faseDelGiorno = fotoOrig.faseDelGiorno; fotoMsk.giornata = fotoOrig.giornata; // il nome del file, lo memorizzo solamente relativo // scarto la parte iniziale di tutto il path togliendo il nome della cartella di base delle foto. // Questo perché le stesse foto le devono vedere altri computer della rete che // vedono il percorso condiviso in maniera differente. fotoMsk.nomeFile = Path.Combine(Path.GetDirectoryName(fotoOrig.nomeFile), nomeFotoClone); fotografieRepositorySrv.addNew(fotoMsk); fotografieRepositorySrv.saveChanges(); } catch (Exception ee) { _giornale.Error("Non riesco ad inserire una foto clonata. Nel db non c'è ma nel filesystem si: " + fotoOrig.nomeFile, ee); } AiutanteFoto.creaProvinoFoto(nomeFileDest, fotoMsk); // Libero la memoria occupata dalle immagini, altrimenti esplode. AiutanteFoto.disposeImmagini(fotoMsk, IdrataTarget.Tutte); // Notifico la lista delle foto da mandare in modifica NuovaFotoMsg msg = new NuovaFotoMsg(this, fotoMsk); // msg.descrizione += Configurazione.ID_FOTOGRAFO_ARTISTA; LumenApplication.Instance.bus.Publish(msg); } }
private void aggiungiImmagineAlCanvas(Canvas canvas, Fotografia foto, double x, double y) { try { // Ricavo l'immagine da stampare IImmagine provino; if (usoGrande) { AiutanteFoto.idrataImmagineDaStampare(foto); provino = AiutanteFoto.idrataImmagineGrande(foto); if (Configurazione.UserConfigLumen.tecSogliaStampaProvini == -3) { IGestoreImmagineSrv g = LumenApplication.Instance.getServizioAvviato <IGestoreImmagineSrv>(); IImmagine provino2 = g.creaProvino(provino, 1000); provino = (IImmagine)provino2.Clone(); ((ImmagineWic)provino).bitmapSource.Freeze(); AiutanteFoto.disposeImmagini(foto, IdrataTarget.Originale); AiutanteFoto.disposeImmagini(foto, IdrataTarget.Risultante); } immaginiPaginaPrecedente.Add(provino); } else { AiutanteFoto.idrataImmaginiFoto(foto, IdrataTarget.Provino); provino = foto.imgProvino; } Image img = new Image(); img.Stretch = Stretch.Uniform; img.StretchDirection = StretchDirection.Both; img.SetValue(Canvas.TopProperty, (Double)(sizeLatoH * (y - 1)) + testataH); img.SetValue(Canvas.LeftProperty, (Double)(sizeLatoW * (x - 1) + margin / 2)); img.Width = sizeLatoW - margin; img.Height = sizeLatoH - margin; img.HorizontalAlignment = HorizontalAlignment.Center; img.VerticalAlignment = VerticalAlignment.Center; if (provino != null) { img.RenderSize = new Size(img.Width, img.Height); // TODO tento di tenere bassa la memoria img.BeginInit(); BitmapSource bs = ((ImmagineWic)provino).bitmapSource; img.Source = bs; img.EndInit(); } canvas.Children.Add(img); } catch (Exception ee) { // Non rilancio l'eccezione perché voglio continuare a stampare _giornale.Error("Impossibile caricare immagime della foto: " + foto, ee); } eventualiStampigli(canvas, x, y, foto); }
/** * Attenzione: * questo metodo deve ritornare l'esito della stampa, quindi non deve essere asincrono. * Deve essere sicronizzato */ public EsitoStampa esegui(LavoroDiStampa lavoroDiStampa) { LavoroDiStampaFoto _lavoroDiStampa = lavoroDiStampa as LavoroDiStampaFoto; _giornale.Debug("Sto per avviare il lavoro di stampa: " + lavoroDiStampa.ToString()); _conta++; try { string nomeFileFoto = AiutanteFoto.idrataImmagineDaStampare(_lavoroDiStampa.fotografia); // Ricavo l'immagine da stampare IImmagine immagine = _lavoroDiStampa.fotografia.imgRisultante != null ? _lavoroDiStampa.fotografia.imgRisultante : _lavoroDiStampa.fotografia.imgOrig; // Gestisco una eccezione specifica, in questo modo ho un messaggio chiaro di cosa è andato storto. if (immagine == null) { throw new FileNotFoundException("fotografia = " + _lavoroDiStampa.fotografia, _lavoroDiStampa.fotografia.nomeFile); } // Devo clonare l'immagine perché negli atri thread potrebbero eseguire delle dispose che me la svuotano using (IImmagine immagineDaStampare = (IImmagine)immagine.Clone()) { // TODO BLUCA provo a duplicare l'immagine per evitare l'errore che è di proprietà del thread chiamante. // BitmapSource bmp = new WriteableBitmap( ((ImmagineWic)immagineDaStampare).bitmapSource ); // bmp.Freeze(); BitmapSource bmp = ((ImmagineWic)immagineDaStampare).bitmapSource; var match = Regex.Match(lavoroDiStampa.param.nomeStampante, @"(?<machine>\\\\.*?)\\(?<queue>.*)"); PrintServer ps1 = null; if (match.Success) { // Come print-server uso il server di rete ps1 = new PrintServer(match.Groups["machine"].Value); } else { // Come print-server uso me stesso ps1 = new PrintServer(); } using ( ps1 ) { PrintQueue coda = null; if (match.Success) { coda = ps1.GetPrintQueue(match.Groups["queue"].Value); } else { coda = ps1.GetPrintQueue(lavoroDiStampa.param.nomeStampante); } // Ricavo la coda di stampa (cioè la stampante) e le sue capacità. using ( coda ) { PrintCapabilities capabilities = null; try { capabilities = coda.GetPrintCapabilities(); } catch (Exception) { // Le stampanti shinko non supportano } // Imposto la stampante (così che mi carica le impostazioni) PrintDialog dialog = new PrintDialog(); dialog.PrintQueue = coda; Size areaStampabile = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight); // Imposto qualche attributo della stampa bool piuRealistaDelRe = false; if (piuRealistaDelRe) // Meglio non essere più realisti del re. { dialog.PrintTicket.OutputQuality = OutputQuality.Photographic; dialog.PrintTicket.PhotoPrintingIntent = PhotoPrintingIntent.PhotoBest; } // Compongo il titolo della stampa che comparirà nella descrizione della riga nello spooler di windows StringBuilder titolo = new StringBuilder(); titolo.AppendFormat("foto N.{0} Oper={1} gg={2}", _lavoroDiStampa.fotografia.etichetta, _lavoroDiStampa.fotografia.fotografo.iniziali, String.Format("{0:dd-MMM}", _lavoroDiStampa.fotografia.dataOraAcquisizione)); #if DEBUG titolo.Append(" #"); titolo.Append(DateTime.Now.ToString("mmssss")); // Uso un numero univoco per evitare doppioni per il doPdf altrimenti mi chiede sempre di sovrascrivere #endif // Eventuale rotazione dell'orientamento dell'area di stampa // Devo decidere in anticipo se la stampante va girata. Dopo che ho chiamato Print non si può più fare !!! bool _ruotareStampante = false; if (_lavoroDiStampa.param.autoRuota) { if (!ProiettoreArea.isStessoOrientamento(areaStampabile, immagineDaStampare)) { _ruotareStampante = true; } } if (_ruotareStampante) { if (capabilities != null && capabilities.PageOrientationCapability.Contains(PageOrientation.Landscape) && capabilities.PageOrientationCapability.Contains(PageOrientation.Portrait)) { // tutto ok dialog.PrintTicket.PageOrientation = (dialog.PrintTicket.PageOrientation == PageOrientation.Landscape ? PageOrientation.Portrait : PageOrientation.Landscape); } else { _giornale.Debug("La stampante " + lavoroDiStampa.param.nomeStampante + " non accetta cambio orientamento landscape/portrait"); } // Quando giro la stampante, non mi si girano anche le dimensioni. Ci penso da solo. areaStampabile = ProiettoreArea.ruota(areaStampabile); } // // ----- gestisco il numero di copie // int cicliStampa = 1; if (lavoroDiStampa.param.numCopie > 1) { // Se la stampante gestisce le copie multiple, faccio un invio solo. if (capabilities != null && capabilities.MaxCopyCount >= lavoroDiStampa.param.numCopie) { dialog.PrintTicket.CopyCount = lavoroDiStampa.param.numCopie; } else { cicliStampa = lavoroDiStampa.param.numCopie; } } // // ----- Preparo la realizzazione grafica da mandare in output // // Ora creo il documento che andrò a stampare. // L'uso di un FixedDocument, mi permetterà di interagire con misure, dimensioni e margini FixedDocument document = new FixedDocument(); document.DocumentPaginator.PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight); // Creo una pagina della grandezza massima FixedPage page1 = new FixedPage(); page1.Width = document.DocumentPaginator.PageSize.Width; page1.Height = document.DocumentPaginator.PageSize.Height; page1.VerticalAlignment = VerticalAlignment.Center; page1.HorizontalAlignment = HorizontalAlignment.Center; // Per fare in modo che l'immagine venga centrata bene automaticamente, e non venga tagliata solo da una parte ma nel centro, // non devo mettere le dimensioni al componente Image, ma devo creare // una Grid più esterna con le dimensioni precise. Grid grid = new Grid(); grid.Height = page1.Height; grid.Width = page1.Width; // Creo una immagine che contiene la bitmap da stampare Image image = new Image(); // image.BeginInit(); image.VerticalAlignment = VerticalAlignment.Center; image.HorizontalAlignment = HorizontalAlignment.Center; // BitmapSource clone = bmp.Clone(); // clone.Freeze(); image.Source = bmp; if (_lavoroDiStampa.param.autoZoomNoBordiBianchi) { image.Stretch = Stretch.UniformToFill; } else { image.Stretch = Stretch.Uniform; } image.StretchDirection = StretchDirection.Both; // image.EndInit(); grid.Children.Add(image); page1.Children.Add(grid); // eventualiStampigli(page1, _lavoroDiStampa); // add the page to the document PageContent page1Content = new PageContent(); page1Content.Child = page1; document.Pages.Add(page1Content); // // ----- STAMPA per davvero // for (int ciclo = 0; ciclo < cicliStampa; ciclo++) { dialog.PrintDocument(document.DocumentPaginator, titolo.ToString()); _esito = EsitoStampa.Ok; } _giornale.Debug("Stampa completata"); // Per cercare di liberare memoria più possibile svuoto le pagine forzatamente a mano. // Pare che il GC non riesce a pulire. foreach (var fixedPage in document.Pages.Select(pageContent => pageContent.Child)) { fixedPage.Children.Clear(); } } // using printqueue } // using printserver } // using iimagine } catch (Exception ee) { _esito = EsitoStampa.Errore; _giornale.Error("Stampa fallita", ee); } finally { // Rilascio le immagini idratate altrimenti in loop vado in outOfMemory AiutanteFoto.disposeImmagini(_lavoroDiStampa.fotografia, IdrataTarget.Risultante); AiutanteFoto.disposeImmagini(_lavoroDiStampa.fotografia, IdrataTarget.Originale); CoreUtil.abraCadabra(); // :-) } _giornale.Info("Completato lavoro di stampa. Esito = " + _esito + " lavoro = " + lavoroDiStampa.ToString()); return(_esito); }
/// <summary> /// Il parametro passato "tempoScarico" deve essere ribaltato su tutte le foto, perché /// serve a creare una relazione implicita 1-n tra lo ScaricoCard e Fotografia /// </summary> /// <param name="tempoScarico"></param> public void elabora(DateTime tempoScarico) { _giornale.Debug("Inizio ad elaborare le foto acquisite"); // carico il fotografo che rimane uguale per tutta questa sessione di elaborazione LumenEntities objContext = UnitOfWorkScope.currentDbContext; _fotografo = objContext.Fotografi.Single <Fotografo>(ff => ff.id == _paramScarica.flashCardConfig.idFotografo); // carico l'evento che rimane uguale per tutta questa sessione di elaborazione if (_paramScarica.flashCardConfig.idEvento != null && _paramScarica.flashCardConfig.idEvento != Guid.Empty) { _evento = objContext.Eventi.SingleOrDefault(e => e.id == _paramScarica.flashCardConfig.idEvento); } _giornale.Debug("Sto per lavorare le " + _listaFiles.Count + " foto appena acquisite di " + _fotografo.id); int ultimoNumFoto = NumeratoreFotogrammi.incrementaNumeratoreFoto(_listaFiles.Count); contaAggiunteDb = 0; ScaricoFotoMsg scaricoFotoMsg = new ScaricoFotoMsg(this, "Notifica progresso"); scaricoFotoMsg.fase = FaseScaricoFoto.Provinatura; scaricoFotoMsg.esitoScarico = new EsitoScarico(); scaricoFotoMsg.esitoScarico.totFotoScaricate = _listaFiles.Count; scaricoFotoMsg.sorgente = _paramScarica.cartellaSorgente != null ? _paramScarica.cartellaSorgente : _paramScarica.nomeFileSingolo; scaricoFotoMsg.showInStatusBar = false; IList <Fotografia> fotoDaEsaminare = null; if (_paramScarica.ricercaBarCode) { fotoDaEsaminare = new List <Fotografia>(); } foreach (FileInfo fileInfo in _listaFiles) { // Eseguo una transazione per ogni foto, in questo modo sono sicuro che tutto quello che posso buttare dentro, ci va. using (TransactionScope transaction = new TransactionScope()) { try { int proxNum = 1 + contaAggiunteDb + ultimoNumFoto; Fotografia foto = aggiungiFoto(fileInfo, proxNum, tempoScarico); // // --- eventuale maschera automatica if (_paramScarica.mascheraAuto != null) { // Uso la maschera nella sua dimensione naturale Imaging.Correzioni.Mascheratura mascheraratura = new Imaging.Correzioni.Mascheratura { nome = _paramScarica.mascheraAuto.nomeFile, width = _paramScarica.mascheraAuto.imgOriginale.ww, height = _paramScarica.mascheraAuto.imgOriginale.hh }; fotoRitoccoSrv.addCorrezione(foto, mascheraratura, false); } // Mark the transaction as complete. transaction.Complete(); // Incremento qui il contatore perché in caso di eccezione, voglio che non si incrementi ++contaAggiunteDb; _giornale.Debug("Inizio Provinatura immagine " + fileInfo.FullName); AiutanteFoto.creaProvinoFoto(fileInfo.FullName, foto); _giornale.Debug("Fine Provinatura immagine "); // Libero la memoria occupata dalle immagini, altrimenti esplode. AiutanteFoto.disposeImmagini(foto, IdrataTarget.Tutte); if (_paramScarica.ricercaBarCode) { fotoDaEsaminare.Add(foto); } // Se lavoro con una singola foto, allora lancio l'evento che mi dice che è pronta. if (String.IsNullOrEmpty(_paramScarica.nomeFileSingolo) == false) { // Quando sono a posto con la foto, sollevo un evento per avvisare tutti // Siccome questa operazione è un pò onerosa, per il momento la abilito // soltanto sulla singola foto. Se ne scarico 1000 di foto, non voglio lanciare 1000 eventi!!! NuovaFotoMsg msg = new NuovaFotoMsg(this, foto); LumenApplication.Instance.bus.Publish(msg); } _giornale.Debug("ok nuova foto provinata e inserita nel db: " + foto); if (contaAggiunteDb % 20 == 0) { scaricoFotoMsg.esitoScarico.totFotoProvinateProg = contaAggiunteDb; LumenApplication.Instance.bus.Publish(scaricoFotoMsg); } } catch (Exception ee) { transaction.Dispose(); _giornale.Error("Errore elaborazione foto. Viene ignorata " + fileInfo, ee); } } } if (_paramScarica.ricercaBarCode) { barCodeSrv.scan(fotoDaEsaminare); } if (contaAggiunteDb != 0) { scaricoFotoMsg.esitoScarico.totFotoProvinateProg = contaAggiunteDb; scaricoFotoMsg.esitoScarico.totFotoProvinate = contaAggiunteDb; LumenApplication.Instance.bus.Publish(scaricoFotoMsg); } _giornale.Info("Terminato di lavorare " + _listaFiles.Count + " foto appena acquisite"); incrementaTotaleFotoScaricate(tempoScarico); }