// Spludlow Software
// Copyright © Samuel P. Ludlow 2020 All Rights Reserved
// Distributed under the terms of the GNU General Public License version 3
// Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
// https://www.spludlow.co.uk/LICENCE.TXT
// The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission
// v1.14
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
namespace Spludlow.MetSat
{
///
/// Back end code for http://metsat.spludlow.co.uk/
///
/// A functioning "Spludlow MetSat" database & store must be available
///
/// These methods are ran from the Spludlow Scheduler to periodically query the Spludlow MetSat database & store to produce the bitmaps for the web
///
/// Each implimented product has its own method and output directory.
///
/// The web works from the output directories only
///
public class WebImagesBack
{
public static string _ImageRootDirectory = Spludlow.Config.Get("MetSatWeb.FilePath");
public static string _MetSatStoreDireectory = Spludlow.Config.Get("MetSat.Store");
public static string _ConnectionString = "@MetSat";
public static bool _TestMode = false;
public static int _DaysBack = 14;
public static string _LogoFilename = @"C:\ProgramData\SpludlowV1\Data\MetSat\SpludlowLogo40mm300dpi.png";
//
// Back End Wrapper methods for the scheduler to call
//
public static void StartDailyProcesses()
{
Spludlow.Call.Queue(Environment.MachineName, "Spludlow.MetSat", "Spludlow.MetSat.WebImagesBack", "CleanUp");
string[] methods = new string[] { "CloudMaskDaySheet", "ChannelsDaySheet", "IndianOceanCloudMaskDaySheet", "IndianOceanChannelsDaySheet" };
foreach (string method in methods)
Spludlow.Call.Queue(Environment.MachineName, "Spludlow.MetSat", "Spludlow.MetSat.WebImagesBack", method);
}
public static void StartRegularProcesses()
{
string[] methods = new string[] { "FalseColour", "FalseColourCrop", "WaterVapour", "IndianOceanFalseColour", "IndianOceanFalseColourCrop", "IndianOceanWaterVapour" };
foreach (string method in methods)
Spludlow.Call.Queue(Environment.MachineName, "Spludlow.MetSat", "Spludlow.MetSat.WebImagesBack", method);
}
public static void CloudMaskDaySheet()
{
CloudMaskSheets(_ImageRootDirectory + @"\CloudMaskDaySheet", "EO_EUM_DAT_MSG_CLM", "Spludlow - EUMETSAT - Meteosat 11 - 0 Degrees - SEVIRI - Cloud Mask Day Sheet - ");
}
public static void ChannelsDaySheet()
{
ChannelsSheets(_ImageRootDirectory + @"\ChannelsDaySheet", "EO_EUM_DAT_MSG_HRSEVIRI", "Spludlow - EUMETSAT - Meteosat 11 - 0 Degrees - SEVIRI - Channels Day Sheet - ");
}
public static void FalseColour()
{
FalseColourBitmap(_ImageRootDirectory + @"\FalseColour", "EO_EUM_DAT_MSG_HRSEVIRI", "Spludlow - EUMETSAT - Meteosat 11 - 0 Degrees - SEVIRI - False Colour - ", false, false);
}
public static void FalseColourCrop()
{
FalseColourBitmap(_ImageRootDirectory + @"\FalseColourCrop", "EO_EUM_DAT_MSG_HRSEVIRI", "Spludlow - EUMETSAT - Meteosat 11 - 0 Degrees - SEVIRI - HRV False Colour Crop - ", true, false);
}
public static void WaterVapour()
{
ChannelBitmap(_ImageRootDirectory + @"\WaterVapour", "EO_EUM_DAT_MSG_HRSEVIRI", "WV_062", "Spludlow - EUMETSAT - Meteosat 11 - 0 Degrees - SEVIRI - Water Vapour");
}
public static void IndianOceanCloudMaskDaySheet()
{
CloudMaskSheets(_ImageRootDirectory + @"\IndianOceanCloudMaskDaySheet", "EO_EUM_DAT_MSG_CLM-IODC", "Spludlow - EUMETSAT - Meteosat 11 - 41.5 Degrees - SEVIRI - Cloud Mask Day Sheet - ");
}
public static void IndianOceanChannelsDaySheet()
{
ChannelsSheets(_ImageRootDirectory + @"\IndianOceanChannelsDaySheet", "EO_EUM_DAT_MSG_HRSEVIRI-IODC", "Spludlow - EUMETSAT - Meteosat 11 - 41.5 Degrees - SEVIRI - Channels Day Sheet - ");
}
public static void IndianOceanFalseColour()
{
FalseColourBitmap(_ImageRootDirectory + @"\IndianOceanFalseColour", "EO_EUM_DAT_MSG_HRSEVIRI-IODC", "Spludlow - EUMETSAT - Meteosat 11 - 41.5 Degrees - SEVIRI - False Colour - ", false, true);
}
public static void IndianOceanFalseColourCrop()
{
FalseColourBitmap(_ImageRootDirectory + @"\IndianOceanFalseColourCrop", "EO_EUM_DAT_MSG_HRSEVIRI-IODC", "Spludlow - EUMETSAT - Meteosat 11 - 41.5 Degrees - SEVIRI - HRV False Colour Crop - ", true, true);
}
public static void IndianOceanWaterVapour()
{
ChannelBitmap(_ImageRootDirectory + @"\IndianOceanWaterVapour", "EO_EUM_DAT_MSG_HRSEVIRI-IODC", "WV_062", "Spludlow - EUMETSAT - Meteosat 11 - 41.5 Degrees - SEVIRI - Water Vapour - ");
}
///
/// Create PDFs of each days 96 cloud mask bitmaps placed into a grid on an A3 document
/// Thumbnails also generated
/// Run once daily using the Spludlow Scheduler
///
public static void CloudMaskSheets(string targetDirectory, string productId, string fullText)
{
if (Directory.Exists(targetDirectory) == false)
Directory.CreateDirectory(targetDirectory);
string filenamePrefix = fullText.Replace(" ", "");
int placedImageDPI = 300;
// Query the database
DateTime startDate = DateTime.Now.Date.AddDays(-_DaysBack);
Spludlow.Data.IDAL database = Spludlow.Data.DAL.Create(_ConnectionString);
DataTable table = database.Select(
"SELECT DataItems.CaptureTime, DataItemFiles.* FROM DataItems INNER JOIN DataItemFiles ON DataItems.DataItemId = DataItemFiles.DataItemId " +
"WHERE((DataItems.DataProductId = @DataProductId) AND (DataItemFiles.DataItemFileTypeId = 'CH') AND (DataItems.CaptureTime >= @CaptureTime)) " +
"ORDER BY DataItems.CaptureTime", productId, startDate);
table = SetKeyRemovingDupRows(table, new string[] { "CaptureTime" }, true);
// Page geometry
float xOffset = 3;
float yOffset = 18;
float thumbSize = 32;
float thumbBoarder = 1.25F;
float boxSize = thumbSize + thumbBoarder * 2;
int pixels = Spludlow.Printing.PageSizes.MillimetersToPixels(thumbSize, placedImageDPI);
Size size = new Size(pixels, pixels);
// For each date in the data
foreach (DateTime captureDate in GetCaptureDates(table))
{
// Skip today as will be incomplete
if (captureDate.Date == DateTime.Now.Date)
continue;
// Name things
string pdfFilename = targetDirectory + @"\" + filenamePrefix + captureDate.ToString("yyyy-MM-dd") + ".pdf";
// Skip if done already
if (File.Exists(pdfFilename) == true)
continue;
using (Spludlow.TempDirectory tempDir = new Spludlow.TempDirectory())
{
// Create a Print doc
Spludlow.Printing.PrintDoc doc = new Spludlow.Printing.PrintDoc("A3*");
// Print hte titla
doc.Text(fullText + captureDate.ToShortDateString(), "Arial, 24, Bold, Underline", 4, 4);
for (int index = 0; index < 96; ++index)
{
// Do the maths for bitmap placment
int xIndex = index % 12;
int yIndex = index / 12;
float x = xOffset + thumbBoarder + xIndex * boxSize;
float y = yOffset + thumbBoarder + yIndex * boxSize;
// Find the date's row
DateTime itemDateTime = captureDate.AddMinutes(index * 15);
DataRow row = table.Rows.Find(itemDateTime);
if (row != null)
{
// Get the store filename
string extention = (string)row["StoreExtention"];
string storeFilename = Spludlow.Io.FileStore.FilePath((long)row["DataItemFileId"], _MetSatStoreDireectory, extention, false);
// Res-size to temp file
string tempFilename = tempDir.Path + @"\" + Spludlow.Text.TimeStamp(itemDateTime) + extention;
Spludlow.Drawing.Bitmaps.Resize(storeFilename, size, tempFilename, ImageFormat.Png, PixelFormat.Format24bppRgb, placedImageDPI);
// Place the re-sized image in the print doc
doc.Place(tempFilename, x, y, 1, 1);
}
else
{
doc.Rectangle(x, y, thumbSize, thumbSize, 0, Color.Empty, Color.Black);
}
// Draw a boarder rounf the bitmap
doc.Rectangle(x - thumbBoarder, y - thumbBoarder, boxSize, boxSize, 1.0F, Color.Red, Color.Empty);
}
// Print the PDF
Spludlow.Printing.Printer.Print(doc, "pdf", pdfFilename, true);
File.SetLastWriteTime(pdfFilename, captureDate);
// Print the thumbnail bitmaps
SaveThumbnalsFromDocument(doc, pdfFilename, captureDate);
}
if (_TestMode == true)
break;
}
}
///
/// Generate daily HRIT Sheets as a PDF with low res placed bitmaps and a JPEG Thumbnail
///
public static void ChannelsSheets(string targetDirectory, string productId, string fullText)
{
if (Directory.Exists(targetDirectory) == false)
Directory.CreateDirectory(targetDirectory);
int placedImageDPI = 300;
string filenamePrefix = fullText.Replace(" ", "");
// Query the database
DateTime startDate = DateTime.Now.Date.AddDays(-_DaysBack);
Spludlow.Data.IDAL database = Spludlow.Data.DAL.Create(_ConnectionString);
DataTable table = database.Select(
"SELECT DataItems.CaptureTime, DataItemFiles.* FROM DataItems INNER JOIN DataItemFiles ON DataItems.DataItemId = DataItemFiles.DataItemId " +
"WHERE((DataItems.DataProductId = @DataProductId) AND (DataItemFiles.DataItemFileTypeId = 'CH') AND (DataItems.CaptureTime >= @CaptureTime)) " +
"ORDER BY DataItems.CaptureTime, DataItemFiles.Channel", productId, startDate);
table = SetKeyRemovingDupRows(table, new string[] { "CaptureTime", "Channel" }, true);
DateTime[] captureDates = GetCaptureDates(table);
string[] channels = new string[] { "IR_016", "IR_039", "IR_087", "IR_097", "IR_108", "IR_120", "IR_134", "VIS006", "VIS008", "WV_062", "WV_073" };
float xOffset = 20;
float yOffset = 18;
float thumbSize = 32;
float thumbBoarder = 1.25F;
float boxSize = thumbSize + thumbBoarder * 2;
int pixels = Spludlow.Printing.PageSizes.MillimetersToPixels(thumbSize, placedImageDPI);
Size size = new Size(pixels, pixels);
foreach (DateTime captureDate in captureDates)
{
if (captureDate.Date == DateTime.Now.Date)
continue;
string pdfFilename = targetDirectory + @"\" + filenamePrefix + captureDate.ToString("yyyy-MM-dd") + ".pdf";
if (File.Exists(pdfFilename) == true)
continue;
using (Spludlow.TempDirectory tempDir = new Spludlow.TempDirectory())
{
Spludlow.Printing.PrintDoc doc = new Spludlow.Printing.PrintDoc("A3*");
doc.Text(fullText + captureDate.ToShortDateString(), "Arial, 24, Bold, Underline", 4, 4);
for (int timeIndex = 0; timeIndex < 8; ++timeIndex)
{
for (int channelIndex = 0; channelIndex < channels.Length; ++channelIndex)
{
string channel = channels[channelIndex];
float x = xOffset + thumbBoarder + channelIndex * boxSize;
float y = yOffset + thumbBoarder + timeIndex * boxSize;
DateTime itemDateTime = captureDate.AddHours(timeIndex * 3);
DataRow row = table.Rows.Find(new object[] { itemDateTime, channel });
if (row != null)
{
string extention = (string)row["StoreExtention"];
string storeFilename = Spludlow.Io.FileStore.FilePath((long)row["DataItemFileId"], _MetSatStoreDireectory, extention, false);
string tempFilename = tempDir.Path + @"\" + Spludlow.Text.TimeStamp(itemDateTime) + "-" + channel + extention;
Spludlow.Drawing.Bitmaps.Resize(storeFilename, size, tempFilename, ImageFormat.Png, PixelFormat.Format24bppRgb, placedImageDPI);
doc.Place(tempFilename, x, y, 1, 1);
}
else
{
doc.Rectangle(x, y, thumbSize, thumbSize, 0, Color.Empty, Color.Black);
}
doc.Rectangle(x - thumbBoarder, y - thumbBoarder, boxSize, boxSize, 1.0F, Color.Red, Color.Empty);
}
}
// Print the PDF
Spludlow.Printing.Printer.Print(doc, "pdf", pdfFilename, true);
File.SetLastWriteTime(pdfFilename, captureDate);
// Print the thumbnail bitmaps
SaveThumbnalsFromDocument(doc, pdfFilename, captureDate);
}
if (_TestMode == true)
break;
}
}
///
/// Create the High Res Visable Full Earth & Western Europe Bitmaps with thumbnails
///
/// Run on Scheduler on the hour just after Spludlow MetSat Process
///
/// Query all "EO_EUM_DAT_MSG_HRSEVIRI" "Source Archive Records" in the Spludlow MetSat Database (3 hourly XRIT)
/// For interested hours only, 6am -> 6pm, day time
/// If file has not all ready been processed
/// Process "Source Archive" into PNG Crop
/// Stamp on the logo and info
/// Save out JPEG full size and JPEG thumnail for the web server
///
public static int FalseColourBitmap(string targetDirectory, string productId, string fullText, bool cropHrv, bool indian)
{
if (Directory.Exists(targetDirectory) == false)
Directory.CreateDirectory(targetDirectory);
int[] hours;
if (indian == false)
hours = new int[] { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };
else
hours = new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
string filenamePrefix = fullText.Replace(" ", "");
// Query metsat database for all interested product files
DateTime startDate = DateTime.Now.Date.AddDays(-_DaysBack);
Spludlow.Data.IDAL database = Spludlow.Data.DAL.Create(_ConnectionString);
DataTable table = database.Select(
"SELECT DataItems.CaptureTime, DataItemFiles.* FROM DataItems INNER JOIN DataItemFiles ON DataItems.DataItemId = DataItemFiles.DataItemId " +
"WHERE((DataItems.DataProductId = @DataProductId) AND (DataItemFiles.DataItemFileTypeId = 'SA') AND (DataItems.CaptureTime >= @CaptureTime)) " +
"ORDER BY DataItems.CaptureTime", productId, startDate);
table = SetKeyRemovingDupRows(table, new string[] { "CaptureTime" }, true);
DateTime[] captureDates = GetCaptureDates(table);
int count = 0;
if (cropHrv == false)
fullText = "";
foreach (DateTime captureDate in captureDates)
{
foreach (int hour in hours)
{
// Find the data row
DateTime itemDateTime = captureDate.AddHours(hour);
DataRow row = table.Rows.Find(new object[] { itemDateTime });
if (row == null)
continue;
string name = filenamePrefix + itemDateTime.ToString("yyyy-MM-dd-HH");
string stampText = fullText + itemDateTime.ToString();
// Get the store filename
string extention = (string)row["StoreExtention"];
string storeFilename = Spludlow.Io.FileStore.FilePath((long)row["DataItemFileId"], _MetSatStoreDireectory, extention, false);
string masterFilename = targetDirectory + @"\" + name + ".master.png"; // Cropped Xrit2Pic output
string stampFilename = targetDirectory + @"\" + name + ".png"; // Stamped with log and text
string imageFilename = targetDirectory + @"\" + name + ".jpg"; // Full size JPEG
// Already processed
if (File.Exists(imageFilename) == true)
continue;
// The composite source image moves around depending on time of day, these numbers seem to work
int xCrop = 0;
if (indian == false)
{
if (hour == 15)
xCrop = 946;
if (hour == 18)
xCrop = 946 * 4;
}
else
{
if (hour == 15)
xCrop = 946 * 3;
}
try
{
// Process and crop the original "SA" (Source Archive) files
FalseColourProcess(storeFilename, masterFilename, xCrop, cropHrv);
// Stamp on the logo and info
StampImage(masterFilename, stampFilename, _LogoFilename, stampText, Color.DeepSkyBlue);
Size originalSize = Spludlow.Drawing.Bitmaps.Dimensions(stampFilename);
// Save out a Full JPEG
Spludlow.Drawing.Bitmaps.Resize(stampFilename, originalSize, imageFilename, ImageFormat.Jpeg, PixelFormat.Format24bppRgb, 300);
File.SetLastWriteTime(imageFilename, itemDateTime);
// Save out a Thumbs JPEG
SaveTumbnailsFromBitmap(stampFilename, itemDateTime);
}
catch (Exception ee)
{
Spludlow.Log.Error("FalseColourBitmap: " + itemDateTime + ", " + storeFilename, ee);
}
// Delete intimediate files
if (File.Exists(masterFilename) == true)
File.Delete(masterFilename);
if (File.Exists(stampFilename) == true)
File.Delete(stampFilename);
if (_TestMode == true)
return count;
}
}
return count;
}
///
/// Extract an XRIT "Source Archive" from the Spludlow MetSat Store
/// Run Xrti2pic against the files to create a High Res Visable PGM bitmap
/// Convert to PNG
/// Crop image for Western Europe
/// Save out target PNG
///
private static void FalseColourProcess(string sourceArchiveFilename, string targetFilename, int x, bool hrvlum)
{
int dpi = 600;
using (Spludlow.TempDirectory tempDir = new Spludlow.TempDirectory())
{
string sourceArchiveDirectory = tempDir + @"\source";
Directory.CreateDirectory(sourceArchiveDirectory);
string processedDirectory = tempDir + @"\processed";
Directory.CreateDirectory(processedDirectory);
string imageDirectory = tempDir + @"\image";
Directory.CreateDirectory(imageDirectory);
// Extract archive and get result filenames
Spludlow.Archive.Extract(sourceArchiveFilename, sourceArchiveDirectory);
string[] subDirs = Directory.GetDirectories(sourceArchiveDirectory);
if (subDirs.Length != 1)
throw new ApplicationException("Not one sub Directory");
sourceArchiveDirectory = subDirs[0];
string[] files = Directory.GetFiles(sourceArchiveDirectory);
string imageFilename;
// Run XRIT2PIC to make the false colour image
string xritArguments = "-compose";
if (hrvlum == true)
xritArguments += " -hrvlum";
Spludlow.MetSat.Xrit2Pic.Run(Directory.GetFiles(sourceArchiveDirectory), processedDirectory, xritArguments);
// Get result filename, there should only be one
string[] resultFilenames = Directory.GetFiles(processedDirectory);
if (resultFilenames.Length != 1)
throw new ApplicationException("Not one result file: " + resultFilenames.Length);
string filename = resultFilenames[0];
// Convert to PNG
imageFilename = imageDirectory + @"\" + Path.GetFileNameWithoutExtension(filename) + ".png";
Spludlow.Drawing.PGM.Convert(filename, imageFilename, ImageFormat.Png, dpi);
if (_TestMode == true && hrvlum == true)
File.Copy(imageFilename, targetFilename + ".FULL.png");
// Crop or copy to target
if (hrvlum == true)
Spludlow.Drawing.Bitmaps.Crop(imageFilename, targetFilename, x, 0, 3840, 2160, dpi);
else
File.Copy(imageFilename, targetFilename);
}
}
///
/// Use a previously processed channel bitmap from the Spludlow MetSat Store
///
public static int ChannelBitmap(string targetDirectory, string productId, string channel, string fullText)
{
if (Directory.Exists(targetDirectory) == false)
Directory.CreateDirectory(targetDirectory);
string filenamePrefix = fullText.Replace(" ", "");
// Query metsat database for all interested product files
DateTime startDate = DateTime.Now.Date.AddDays(-_DaysBack);
Spludlow.Data.IDAL database = Spludlow.Data.DAL.Create(_ConnectionString);
DataTable table = database.Select(
"SELECT DataItems.CaptureTime, DataItemFiles.* FROM DataItems INNER JOIN DataItemFiles ON DataItems.DataItemId = DataItemFiles.DataItemId " +
"WHERE((DataItems.DataProductId = @DataProductId) AND (DataItemFiles.Channel = @Channel) AND (DataItems.CaptureTime >= @CaptureTime)) " +
"ORDER BY DataItems.CaptureTime", productId, channel, startDate);
table = SetKeyRemovingDupRows(table, new string[] { "CaptureTime" }, true);
DateTime[] captureDates = GetCaptureDates(table);
int count = 0;
int[] hours = new int[] { 0, 3, 6, 9, 12, 15, 18, 21 };
foreach (DateTime captureDate in captureDates)
{
foreach (int hour in hours)
{
// Find the data row
DateTime itemDateTime = captureDate.AddHours(hour);
DataRow row = table.Rows.Find(new object[] { itemDateTime });
if (row == null)
continue;
string name = filenamePrefix + itemDateTime.ToString("yyyy-MM-dd-HH");
string stampText = itemDateTime.ToString();
// Get the store filename
string extention = (string)row["StoreExtention"];
string storeFilename = Spludlow.Io.FileStore.FilePath((long)row["DataItemFileId"], _MetSatStoreDireectory, extention, false);
string stampFilename = targetDirectory + @"\" + name + ".png"; // Stamped with log and text
string imageFilename = targetDirectory + @"\" + name + ".jpg"; // Full size JPEG
// Already processed
if (File.Exists(imageFilename) == true)
continue;
Size originalSize = Spludlow.Drawing.Bitmaps.Dimensions(storeFilename);
// Stamp on the logo and info
StampImage(storeFilename, stampFilename, _LogoFilename, stampText, Color.Yellow);
// Save out a Full JPEG
Spludlow.Drawing.Bitmaps.Resize(stampFilename, originalSize, imageFilename, ImageFormat.Jpeg, PixelFormat.Format24bppRgb, 300);
File.SetLastWriteTime(imageFilename, itemDateTime);
// Save out a Thumbs JPEG
SaveTumbnailsFromBitmap(stampFilename, itemDateTime);
// Delete intimediate files
File.Delete(stampFilename);
if (_TestMode == true)
return count;
}
}
return count;
}
///
/// Stamp logo and right aligned text
///
/// Using the PrintDoc(bitmap, standardWidth) overload specifically designed for drawing onto bitmaps
///
/// A standard page width of 210mm (A4) is used for drawing operations reguardless of the bitmap size and dpi to make page geometry easy
///
public static void StampImage(string sourceFilename, string targetFilename, string logoFilename, string text, Color colour)
{
int targetDpi = 600;
// Create Print Doc from source bitmap file placed with a familiar width (A4)
Spludlow.Printing.PrintDoc doc = new Spludlow.Printing.PrintDoc(sourceFilename, 210);
float boarder = 2.5F;
// Place the logo (40mm wide)
doc.Place(logoFilename, boarder, boarder, 1.0F, 1);
// Print the info in textbox so we can right alight and handle overflow
doc.TextBox(text, "Rockwell, 12", 45, boarder, 210 - (45 + boarder), 50, colour, StringAlignment.Far);
// Save out target bitmap, "Ignore History" flag set to true as not required
Spludlow.Printing.Printer.Print(doc, "bitmap", targetFilename + ", " + targetDpi, true);
}
///
/// Create thumbnail bitmaps from PrintDoc. Used when doing PDF Sheets
///
public static void SaveThumbnalsFromDocument(Spludlow.Printing.PrintDoc doc, string filename, DateTime lastWriteTime)
{
int[] pixelWidths = new int[] { 960, 480 };
string name = filename.Substring(0, filename.LastIndexOf("."));
foreach (int pixelWidth in pixelWidths)
{
string thumbFilename = name + ".thumb" + pixelWidth + ".jpg";
float dpi = Spludlow.Printing.PageSizes.MillimetersToDpi(doc.Width, pixelWidth);
Spludlow.Printing.Printer.Print(doc, "bitmap", thumbFilename + ", " + dpi, true);
File.SetLastWriteTime(thumbFilename, lastWriteTime);
}
}
///
/// Create thumbnail bitmaps from bitmap.
///
public static void SaveTumbnailsFromBitmap(string filename, DateTime lastWriteTime)
{
int[] pixelWidths = new int[] { 960, 480 };
string name = filename.Substring(0, filename.LastIndexOf("."));
Size originalPixelSize = Spludlow.Drawing.Bitmaps.Dimensions(filename);
foreach (int pixelWidth in pixelWidths)
{
decimal height = originalPixelSize.Height * (pixelWidth / originalPixelSize.Width);
Size thumbSize = new Size(pixelWidth, (int)Math.Round(height, 0));
string thumbFilename = name + ".thumb" + pixelWidth + ".jpg";
Spludlow.Drawing.Bitmaps.Resize(filename, thumbSize, thumbFilename, ImageFormat.Jpeg, PixelFormat.Format24bppRgb, 72);
File.SetLastWriteTime(thumbFilename, lastWriteTime);
}
}
///
/// Get the dates in the data
///
public static DateTime[] GetCaptureDates(DataTable table)
{
List captureDates = new List();
foreach (DataRow row in table.Rows)
{
DateTime captureDate = ((DateTime)row["CaptureTime"]).Date;
if (captureDates.Contains(captureDate) == false)
captureDates.Add(captureDate);
}
captureDates.Sort();
return captureDates.ToArray();
}
///
/// Occoationaly see duplicate rows in the data, probibly from re-starting running processes
/// Should fix further back but this will solve the problem for now
/// Done in reverse order as the last one will be most likly be complete
///
public static DataTable SetKeyRemovingDupRows(DataTable table, string[] keyColumnNames, bool importRowsFromEnd)
{
DataTable resultTable = table.Clone();
DataColumn[] keyColumns = new DataColumn[keyColumnNames.Length];
for (int index = 0; index < keyColumnNames.Length; ++index)
keyColumns[index] = resultTable.Columns[keyColumnNames[index]];
resultTable.PrimaryKey = keyColumns;
List rows = new List();
foreach (DataRow row in table.Rows)
rows.Add(row);
if (importRowsFromEnd == true)
rows.Reverse();
object[] key = new object[keyColumnNames.Length];
foreach (DataRow row in rows)
{
for (int keyIndex = 0; keyIndex < key.Length; ++keyIndex)
key[keyIndex] = row[keyColumnNames[keyIndex]];
if (resultTable.Rows.Find(key) == null)
resultTable.ImportRow(row);
}
// Maybe should put back to right order now reversed ?
return resultTable;
}
public static void CleanUp()
{
DateTime deleteBefore = DateTime.Now.Date.AddDays(-45);
int count = 0;
foreach (string imageDirectory in Directory.GetDirectories(_ImageRootDirectory))
{
DirectoryInfo dirInfo = new DirectoryInfo(imageDirectory);
foreach (FileInfo fileInfo in dirInfo.GetFiles())
{
if (fileInfo.LastWriteTime < deleteBefore)
{
fileInfo.Delete();
++count;
}
}
}
Spludlow.Log.Finish("Web Images Back, Clean Up, Deleted: " + count);
}
}
}