شركة التطبيقات المتكاملة لتصميم النظم البرمجية الخاصة ش.ش.و.

Integrated Applications Programming Company

Skip Navigation LinksHome » Code Library » Image

Public general use code classes and xml files that we've compiled and used over the years:

Image processing support class.

   1:  using System;
   2:  using System.Drawing;
   3:  using System.Drawing.Imaging;
   4:  using System.Drawing.Drawing2D;
   5:  using System.IO;
   6:  using System.Security.Cryptography;
   7:   
   8:  #if WFA
   9:  using System.ComponentModel;
  10:  using System.Windows.Forms;
  11:  #else
  12:  using System.Web;
  13:  #endif
  14:   
  15:  namespace Ia.Cl.Model
  16:  {
  17:      ////////////////////////////////////////////////////////////////////////////
  18:   
  19:      /// <summary publish="true">
  20:      /// Image processing support class.
  21:      /// </summary>
  22:      /// <remarks> 
  23:      /// Copyright � 2001-2022 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
  24:      ///
  25:      /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
  26:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  27:      ///
  28:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  29:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  30:      /// 
  31:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  32:      /// 
  33:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  34:      /// </remarks> 
  35:      public class Image
  36:      {
  37:          ////////////////////////////////////////////////////////////////////////////
  38:   
  39:          /// <summary>
  40:          ///
  41:          /// </summary>
  42:          public Image()
  43:          {
  44:          }
  45:   
  46:          ////////////////////////////////////////////////////////////////////////////
  47:   
  48:          /// <summary>
  49:          ///
  50:          /// </summary>
  51:          public static void CreateGeneralUse(string pathSourceFile)
  52:          {
  53:              CreateGeneralUse(pathSourceFile, pathSourceFile, -1, -1);
  54:          }
  55:   
  56:          ////////////////////////////////////////////////////////////////////////////
  57:   
  58:          /// <summary>
  59:          ///
  60:          /// </summary>
  61:          public static void CreateGeneralUse(string pathSourceFile, string pathDestinationPath)
  62:          {
  63:              CreateGeneralUse(pathSourceFile, pathDestinationPath, -1, -1);
  64:          }
  65:   
  66:          ////////////////////////////////////////////////////////////////////////////
  67:   
  68:          /// <summary>
  69:          ///
  70:          /// </summary>
  71:          public static void CreateGeneralUse(string sourceFilePath, string destinationPath, int num, int suffix)
  72:          {
  73:              // resize main image and generate images of the different formats
  74:              string name, extension;//, absolutePath;
  75:   
  76:              // we will check if paths are absolute or relative and adjust them accordingly.
  77:   
  78:              sourceFilePath = AbsolutePath(sourceFilePath);
  79:              destinationPath = AbsolutePath(destinationPath);
  80:   
  81:              try
  82:              {
  83:                  System.Drawing.Image image = System.Drawing.Image.FromFile(sourceFilePath);
  84:   
  85:                  extension = System.IO.Path.GetExtension(sourceFilePath);
  86:                  extension = extension.ToLower();
  87:   
  88:                  // this solves a bug:
  89:                  image.RotateFlip(RotateFlipType.Rotate180FlipNone);
  90:                  image.RotateFlip(RotateFlipType.Rotate180FlipNone);
  91:   
  92:                  // below; this generates images that assume the original image has dimentions ration of 4:3 (1024:768)
  93:                  // generate tiny, small, middle, and large size images and the sample image:
  94:   
  95:                  // this will generate images that have a fixed "area". This will preserve the original width-height ratio, but will
  96:                  // also give a scaled, suitable versions:
  97:   
  98:                  // note that if w0*h0=A0 and w*h=Af, then h=h0*(sqrt(Af))/(sqrt(A)) and  w=w0*(sqrt(Af))/(sqrt(A))
  99:   
 100:                  double w, h, A, Af, r, w2, h2;
 101:                  w = image.Width; h = image.Height;
 102:                  A = w * h;
 103:   
 104:                  System.Drawing.Image.GetThumbnailImageAbort dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
 105:   
 106:                  Af = 640 * 480;
 107:                  if (Af > A) Af = A;
 108:                  r = Math.Sqrt(Af) / Math.Sqrt(A);
 109:                  System.Drawing.Image veryLarge = image.GetThumbnailImage(Convert.ToInt32(w * r), Convert.ToInt32(h * r), dummyCallBack, IntPtr.Zero);
 110:   
 111:                  Af = 400 * 300;
 112:                  if (Af > A) Af = A;
 113:                  r = Math.Sqrt(Af) / Math.Sqrt(A);
 114:                  System.Drawing.Image large = image.GetThumbnailImage(Convert.ToInt32(w * r), Convert.ToInt32(h * r), dummyCallBack, IntPtr.Zero);
 115:   
 116:                  Af = 200 * 150;
 117:                  if (Af > A) Af = A;
 118:                  r = Math.Sqrt(Af) / Math.Sqrt(A);
 119:                  System.Drawing.Image middle = image.GetThumbnailImage(Convert.ToInt32(w * r), Convert.ToInt32(h * r), dummyCallBack, IntPtr.Zero);
 120:   
 121:                  Af = 120 * 90;
 122:                  if (Af > A) Af = A;
 123:                  r = Math.Sqrt(Af) / Math.Sqrt(A);
 124:                  System.Drawing.Image small = image.GetThumbnailImage(Convert.ToInt32(w * r), Convert.ToInt32(h * r), dummyCallBack, IntPtr.Zero);
 125:   
 126:                  Af = 80 * 60;
 127:                  if (Af > A) Af = A;
 128:                  r = Math.Sqrt(Af) / Math.Sqrt(A);
 129:                  System.Drawing.Image tiny = image.GetThumbnailImage(Convert.ToInt32(w * r), Convert.ToInt32(h * r), dummyCallBack, IntPtr.Zero);
 130:   
 131:                  // this saves an exact size version:
 132:                  System.Drawing.Image same = image.GetThumbnailImage(Convert.ToInt32(w), Convert.ToInt32(h), dummyCallBack, IntPtr.Zero);
 133:   
 134:                  // the methods below will generate images with fixed width and varying high. Width range from 75 to 500.
 135:                  System.Drawing.Image image500, image400, image250, image100, image75;
 136:   
 137:                  w2 = 500;
 138:                  h2 = w2 * h / w;
 139:                  image500 = image.GetThumbnailImage(Convert.ToInt32(w2), Convert.ToInt32(h2), dummyCallBack, IntPtr.Zero);
 140:   
 141:                  w2 = 400;
 142:                  h2 = w2 * h / w;
 143:                  image400 = image.GetThumbnailImage(Convert.ToInt32(w2), Convert.ToInt32(h2), dummyCallBack, IntPtr.Zero);
 144:   
 145:                  w2 = 250;
 146:                  h2 = w2 * h / w;
 147:                  image250 = image.GetThumbnailImage(Convert.ToInt32(w2), Convert.ToInt32(h2), dummyCallBack, IntPtr.Zero);
 148:   
 149:                  w2 = 100;
 150:                  h2 = w2 * h / w;
 151:                  image100 = image.GetThumbnailImage(Convert.ToInt32(w2), Convert.ToInt32(h2), dummyCallBack, IntPtr.Zero);
 152:   
 153:                  w2 = 75;
 154:                  h2 = w2 * h / w;
 155:                  image75 = image.GetThumbnailImage(Convert.ToInt32(w2), Convert.ToInt32(h2), dummyCallBack, IntPtr.Zero);
 156:   
 157:                  if (num < 0 && suffix < 0)
 158:                  {
 159:                      name = destinationPath.Replace(".jpg", "");
 160:                  }
 161:                  else if (num < 0) name = destinationPath + "_" + suffix;
 162:                  else if (suffix < 0) name = destinationPath + "_" + num;
 163:                  else name = destinationPath + num + "_" + suffix;
 164:   
 165:                  // 
 166:   
 167:                  //middle = ImageShadow.OnPaint(middle);
 168:   
 169:                  // save new images:
 170:   
 171:                  if (extension == ".jpg")
 172:                  {
 173:                      SaveJpeg(name + "_vl.jpg", veryLarge, 100);
 174:                      SaveJpeg(name + "_l.jpg", large, 100);
 175:                      SaveJpeg(name + "_m.jpg", middle, 100);
 176:                      SaveJpeg(name + "_s.jpg", small, 100);
 177:                      SaveJpeg(name + "_t.jpg", tiny, 100);
 178:                      SaveJpeg(name + ".jpg", same, 100);
 179:   
 180:                      SaveJpeg(name + "_500.jpg", image500, 100);
 181:                      SaveJpeg(name + "_400.jpg", image400, 100);
 182:                      SaveJpeg(name + "_250.jpg", image250, 100);
 183:                      SaveJpeg(name + "_100.jpg", image100, 100);
 184:                      SaveJpeg(name + "_75.jpg", image75, 100);
 185:                  }
 186:                  else
 187:                  {
 188:                      veryLarge.Save(name + "_vl.png", ImageFormat.Png);
 189:                      veryLarge.Dispose();
 190:   
 191:                      large.Save(name + "_l.png", ImageFormat.Png);
 192:                      large.Dispose();
 193:   
 194:                      middle.Save(name + "_m.png", ImageFormat.Png);
 195:                      middle.Dispose();
 196:   
 197:                      small.Save(name + "_s.png", ImageFormat.Png);
 198:                      small.Dispose();
 199:   
 200:                      tiny.Save(name + "_t.png", ImageFormat.Png);
 201:                      tiny.Dispose();
 202:   
 203:                      same.Save(name + ".png", ImageFormat.Png);
 204:                      same.Dispose();
 205:   
 206:   
 207:                      image500.Save(name + "_500.png", ImageFormat.Png);
 208:                      image500.Dispose();
 209:   
 210:                      image400.Save(name + "_400.png", ImageFormat.Png);
 211:                      image400.Dispose();
 212:   
 213:                      image250.Save(name + "_250.png", ImageFormat.Png);
 214:                      image250.Dispose();
 215:   
 216:                      image100.Save(name + "_100.png", ImageFormat.Png);
 217:                      image100.Dispose();
 218:   
 219:                      image75.Save(name + "_75.png", ImageFormat.Png);
 220:                      image75.Dispose();
 221:                  }
 222:   
 223:                  image.Dispose();
 224:              }
 225:              catch (Exception)
 226:              {
 227:              }
 228:          }
 229:   
 230:          ////////////////////////////////////////////////////////////////////////////
 231:   
 232:          /// <summary>
 233:          ///
 234:          /// </summary>
 235:          public static Bitmap CropImage2(Bitmap source, Rectangle section)
 236:          {
 237:              // bad, give bad results
 238:              // https://stackoverflow.com/questions/9484935/how-to-cut-a-part-of-image-in-c-sharp
 239:   
 240:              var bitmap = new Bitmap(section.Width, section.Height);
 241:              using (var g = Graphics.FromImage(bitmap))
 242:              {
 243:                  g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
 244:                  return bitmap;
 245:              }
 246:          }
 247:   
 248:          ////////////////////////////////////////////////////////////////////////////
 249:   
 250:          /// <summary>
 251:          ///
 252:          /// </summary>
 253:          public static Bitmap CropImage(Bitmap source, Rectangle section)
 254:          {
 255:              // https://stackoverflow.com/questions/9484935/how-to-cut-a-part-of-image-in-c-sharp
 256:   
 257:              Bitmap image = source.Clone(section, source.PixelFormat);
 258:   
 259:              return image;
 260:          }
 261:   
 262:          ////////////////////////////////////////////////////////////////////////////
 263:   
 264:          /// <summary>
 265:          ///
 266:          /// </summary>
 267:          public static Bitmap ResizeImage(Bitmap bmp, int width, int height)
 268:          {
 269:              // https://www.tutorialsrack.com/articles/199/how-to-resize-an-image-in-csharp
 270:              Bitmap bitmap = new Bitmap(width, height);
 271:              using (Graphics graphics = Graphics.FromImage(bitmap))
 272:              {
 273:                  graphics.DrawImage(bmp, 0, 0, width, height);
 274:              }
 275:              return bitmap;
 276:          }
 277:   
 278:          ////////////////////////////////////////////////////////////////////////////
 279:   
 280:          /// <summary>
 281:          ///
 282:          /// </summary>
 283:          public static void CropToTheBiggestSquareCenteredInTheMiddleThenResizeToSquareWithSideLength(string sourceFile, string destinationFile, int squareSideLength)
 284:          {
 285:              Bitmap image = new Bitmap(sourceFile);
 286:   
 287:              if (image.Width > squareSideLength && image.Height > squareSideLength)
 288:              {
 289:                  var minOfWidthOrHeight = Math.Min(image.Width, image.Height);
 290:   
 291:                  Rectangle section = new Rectangle(new Point(image.Width / 2 - minOfWidthOrHeight / 2, image.Height / 2 - minOfWidthOrHeight / 2), new Size(minOfWidthOrHeight, minOfWidthOrHeight));
 292:   
 293:                  Bitmap croppedImage = CropImage(image, section);
 294:   
 295:                  croppedImage.Save(destinationFile);
 296:   
 297:                  Bitmap resizedCroppedImage = ResizeImage(croppedImage, squareSideLength, squareSideLength);
 298:   
 299:                  resizedCroppedImage.Save(destinationFile);
 300:              }
 301:              else
 302:              {
 303:                  throw new ArgumentOutOfRangeException("Square side larger than image side");
 304:              }
 305:   
 306:              /*
 307:              var sourceImage = System.Drawing.Image.FromFile(sourceFile);
 308:  
 309:              var extension = System.IO.Path.GetExtension(sourceFile);
 310:              var name = System.IO.Path.GetFileNameWithoutExtension(sourceFile);
 311:              extension = extension.ToLower();
 312:  
 313:              // this solves a bug:
 314:              sourceImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
 315:              sourceImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
 316:  
 317:              var dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
 318:  
 319:              if (sourceImage.Width > squareSideLength && sourceImage.Height > squareSideLength)
 320:              {
 321:                  var sample = sourceImage.GetThumbnailImage(squareSideLength, squareSideLength, dummyCallBack, IntPtr.Zero);
 322:  
 323:                  var graphic = Graphics.FromImage(sample);
 324:  
 325:                  var i = (sourceImage.Width > sourceImage.Height) ? sourceImage.Height : sourceImage.Width;
 326:  
 327:                  try
 328:                  {
 329:                      var dest = new RectangleF(sourceImage.Height / 2, sourceImage.Width / 2, squareSideLength, squareSideLength);
 330:                      var source = new RectangleF(sourceImage.Height / 2, sourceImage.Width / 2, i, i);
 331:                      graphic.DrawImage(sourceImage, dest, source, GraphicsUnit.Pixel);
 332:  
 333:                      if (extension == ".jpg") sample.Save(destinationFile, ImageFormat.Jpeg);
 334:                      else sample.Save(destinationFile, ImageFormat.Png);
 335:  
 336:                      sample.Dispose();
 337:                  }
 338:                  catch (Exception)
 339:                  {
 340:                      //result_l.Text += " "+ex.ToString();
 341:                  }
 342:                  finally
 343:                  {
 344:                      if (null != graphic) graphic.Dispose();
 345:                  }
 346:              }
 347:              else
 348:              {
 349:                  throw new ArgumentOutOfRangeException("Square side larger than image side");
 350:              }
 351:              */
 352:          }
 353:   
 354:          ////////////////////////////////////////////////////////////////////////////
 355:   
 356:          /// <summary>
 357:          ///
 358:          /// </summary>
 359:          public static void CutoutWithWidthAndHeight(string sourceFile, string destinationFile, int width, int height)
 360:          {
 361:              var image = System.Drawing.Image.FromFile(sourceFile);
 362:   
 363:              var extension = System.IO.Path.GetExtension(sourceFile);
 364:              var name = System.IO.Path.GetFileNameWithoutExtension(sourceFile);
 365:              extension = extension.ToLower();
 366:   
 367:              // this solves a bug:
 368:              image.RotateFlip(RotateFlipType.Rotate180FlipNone);
 369:              image.RotateFlip(RotateFlipType.Rotate180FlipNone);
 370:   
 371:              var dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
 372:   
 373:              if (image.Width > width && image.Height > height)
 374:              {
 375:                  var imageN = image.GetThumbnailImage(Convert.ToInt32(image.Width), Convert.ToInt32(image.Height), dummyCallBack, IntPtr.Zero);
 376:   
 377:                  if (extension == ".jpg")
 378:                  {
 379:                      SaveJpeg(destinationFile, imageN, 100);
 380:                  }
 381:                  else
 382:                  {
 383:                      imageN.Save(destinationFile, ImageFormat.Png);
 384:                      imageN.Dispose();
 385:                  }
 386:              }
 387:              else
 388:              {
 389:                  throw new ArgumentOutOfRangeException("Square side larger than image side");
 390:              }
 391:          }
 392:   
 393:          /*
 394:          ////////////////////////////////////////////////////////////////////////////
 395:  
 396:          /// <summary>
 397:          ///
 398:          /// </summary>
 399:  
 400:      public class ImageShadow : Image
 401:      {
 402:          private Color _panelColor;
 403:  
 404:          public Color PanelColor
 405:          {
 406:              get { return _panelColor; }
 407:              set { _panelColor = value; }
 408:          }
 409:  
 410:          private Color _borderColor;
 411:  
 412:          public Color BorderColor
 413:          {
 414:              get { return _borderColor; }
 415:              set { _borderColor = value; }
 416:          }
 417:  
 418:          private int shadowSize = 5;
 419:          private int shadowMargin = 2;
 420:  
 421:          // static for good perfomance 
 422:          static Image shadowDownRight = new Bitmap(typeof(ImageShadow), "Images.tshadowdownright.png");
 423:          static Image shadowDownLeft = new Bitmap(typeof(ImageShadow), "Images.tshadowdownleft.png");
 424:          static Image shadowDown = new Bitmap(typeof(ImageShadow), "Images.tshadowdown.png");
 425:          static Image shadowRight = new Bitmap(typeof(ImageShadow), "Images.tshadowright.png");
 426:          static Image shadowTopRight = new Bitmap(typeof(ImageShadow), "Images.tshadowtopright.png");
 427:  
 428:          public ImageShadow()
 429:          {
 430:          }
 431:  
 432:          public static System.Drawing.Image OnPaint(System.Drawing.Image i)
 433:          {
 434:              // Get the graphics object. We need something to draw with ;-)
 435:              Graphics g = Graphics.FromImage(i);
 436:  
 437:              // Create tiled brushes for the shadow on the right and at the bottom.
 438:              TextureBrush shadowRightBrush = new TextureBrush(shadowRight, WrapMode.Tile);
 439:              TextureBrush shadowDownBrush = new TextureBrush(shadowDown, WrapMode.Tile);
 440:  
 441:              // Translate (move) the brushes so the top or left of the image matches the top or left of the
 442:              // area where it's drawed. If you don't understand why this is necessary, comment it out. 
 443:              // Hint: The tiling would start at 0,0 of the control, so the shadows will be offset a little.
 444:              shadowDownBrush.TranslateTransform(0, Height - shadowSize);
 445:              shadowRightBrush.TranslateTransform(Width - shadowSize, 0);
 446:  
 447:              // Define the rectangles that will be filled with the brush.
 448:              // (where the shadow is drawn)
 449:              Rectangle shadowDownRectangle = new Rectangle(
 450:                  shadowSize + shadowMargin,                      // X
 451:                  Height - shadowSize,                            // Y
 452:                  Width - (shadowSize * 2 + shadowMargin),        // width (stretches)
 453:                  shadowSize                                      // height
 454:                  );                                    
 455:  
 456:              Rectangle shadowRightRectangle = new Rectangle(
 457:                  Width - shadowSize,                             // X
 458:                  shadowSize + shadowMargin,                      // Y
 459:                  shadowSize,                                     // width
 460:                  Height - (shadowSize * 2 + shadowMargin)        // height (stretches)
 461:                  );
 462:  
 463:              // And draw the shadow on the right and at the bottom.
 464:              g.FillRectangle(shadowDownBrush, shadowDownRectangle);
 465:              g.FillRectangle(shadowRightBrush, shadowRightRectangle);
 466:  
 467:              // Now for the corners, draw the 3 5x5 pixel images.
 468:              g.DrawImage(shadowTopRight, new Rectangle(Width - shadowSize, shadowMargin, shadowSize, shadowSize));
 469:              g.DrawImage(shadowDownRight, new Rectangle(Width - shadowSize, Height - shadowSize, shadowSize, shadowSize));
 470:              g.DrawImage(shadowDownLeft, new Rectangle(shadowMargin, Height - shadowSize, shadowSize, shadowSize));
 471:  
 472:              // Fill the area inside with the color in the PanelColor property.
 473:              // 1 pixel is added to everything to make the rectangle smaller. 
 474:              // This is because the 1 pixel border is actually drawn outside the rectangle.
 475:               Rectangle fullRectangle = new Rectangle(
 476:                  1,                                              // X
 477:                  1,                                              // Y
 478:                  Width - (shadowSize + 2),                       // Width
 479:                  Height - (shadowSize + 2)                       // Height
 480:                  );                     
 481:  
 482:              if (PanelColor != null)
 483:              {
 484:                  SolidBrush bgBrush = new SolidBrush(_panelColor);
 485:                  g.FillRectangle(bgBrush, fullRectangle);
 486:              }
 487:  
 488:              // Draw a nice 1 pixel border it a BorderColor is specified
 489:              if (_borderColor != null)
 490:              {
 491:                  Pen borderPen = new Pen(BorderColor);
 492:                  g.DrawRectangle(borderPen, fullRectangle);
 493:              }
 494:  
 495:              // Memory efficiency
 496:              shadowDownBrush.Dispose();
 497:              shadowRightBrush.Dispose();
 498:  
 499:              shadowDownBrush = null;
 500:              shadowRightBrush = null;
 501:          }
 502:      }
 503:  
 504:           */
 505:   
 506:          ////////////////////////////////////////////////////////////////////////////
 507:   
 508:          /// <summary>
 509:          ///
 510:          /// </summary>
 511:          private static bool SaveJpeg(string fileName, System.Drawing.Image image, long nQuality)
 512:          {
 513:              //Syntax: SaveJpeg(filename, image object, quality (1-100))
 514:   
 515:              try
 516:              {
 517:                  // Build image encoder detail
 518:                  var encoders = ImageCodecInfo.GetImageEncoders();
 519:                  var encoderParameters = new EncoderParameters(1);
 520:                  encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, nQuality);
 521:   
 522:                  // Data used "System.Drawing.Imaging" because there is another Encoder in System.Text
 523:   
 524:                  // Get jpg format id
 525:                  foreach (var encoder in encoders)
 526:                  {
 527:                      if (encoder.MimeType == "image/jpeg")
 528:                      {
 529:                          image.Save(fileName, encoder, encoderParameters);
 530:   
 531:                          image.Dispose();
 532:   
 533:                          return true;
 534:                      }
 535:                  }
 536:              }
 537:              catch (Exception)
 538:              {
 539:   
 540:              }
 541:   
 542:              return false;
 543:          }
 544:   
 545:          ////////////////////////////////////////////////////////////////////////////
 546:   
 547:          /// <summary>
 548:          ///
 549:          /// </summary>
 550:          public static void DeleteGeneralUse(string relativePath, int num, int suffix)
 551:          {
 552:              int count;
 553:              string name, absolutePath, r;
 554:              string[] p;
 555:   
 556:              absolutePath = AbsolutePath();
 557:   
 558:              if (num < 0 && suffix < 0) name = absolutePath + relativePath;
 559:              else if (num < 0) name = absolutePath + relativePath + "_" + suffix;
 560:              else if (suffix < 0) name = absolutePath + relativePath + "_" + num;
 561:              else name = absolutePath + relativePath + num + "_" + suffix;
 562:   
 563:              File.Delete(name + "_vl.jpg");
 564:              File.Delete(name + "_l.jpg");
 565:              File.Delete(name + "_m.jpg");
 566:              File.Delete(name + "_s.jpg");
 567:              File.Delete(name + "_t.jpg");
 568:              File.Delete(name + ".jpg");
 569:   
 570:              File.Delete(name + "_500.jpg");
 571:              File.Delete(name + "_400.jpg");
 572:              File.Delete(name + "_250.jpg");
 573:              File.Delete(name + "_100.jpg");
 574:              File.Delete(name + "_75.jpg");
 575:   
 576:              // rearrange images so they stay in sequence
 577:              try
 578:              {
 579:                  // rename all following images so that they fill the name of the missing image:
 580:                  // count images:
 581:                  p = Directory.GetFiles(absolutePath + relativePath, num + @"_*_t.jpg");
 582:   
 583:                  count = p.Length;
 584:   
 585:                  for (int i = suffix; i < count; i++)
 586:                  {
 587:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_vl.jpg", absolutePath + relativePath + num + "_" + i + "_vl.jpg");
 588:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_l.jpg", absolutePath + relativePath + num + "_" + i + "_l.jpg");
 589:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_m.jpg", absolutePath + relativePath + num + "_" + i + "_m.jpg");
 590:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_s.jpg", absolutePath + relativePath + num + "_" + i + "_s.jpg");
 591:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_t.jpg", absolutePath + relativePath + num + "_" + i + "_t.jpg");
 592:                      //File.Move(absolutePath + relative_path + num + "_" + (i + 1) + "_sample.jpg", absolutePath + relative_path + num + "_" + i + "_sample.jpg");
 593:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + ".jpg", absolutePath + relativePath + num + "_" + i + ".jpg");
 594:   
 595:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_500.jpg", absolutePath + relativePath + num + "_" + i + "_500.jpg");
 596:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_400.jpg", absolutePath + relativePath + num + "_" + i + "_400.jpg");
 597:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_250.jpg", absolutePath + relativePath + num + "_" + i + "_250.jpg");
 598:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_100.jpg", absolutePath + relativePath + num + "_" + i + "_100.jpg");
 599:                      File.Move(absolutePath + relativePath + num + "_" + (i + 1) + "_75.jpg", absolutePath + relativePath + num + "_" + i + "_75.jpg");
 600:                  }
 601:              }
 602:              catch (Exception ex)
 603:              {
 604:  #if DEBUG
 605:                  r = "Error: " + ex.ToString();
 606:  #else
 607:                  r = "Error: " + ex.Message;
 608:  #endif
 609:              }
 610:              finally
 611:              {
 612:              }
 613:          }
 614:   
 615:          ////////////////////////////////////////////////////////////////////////////
 616:   
 617:          /// <summary>
 618:          ///
 619:          /// </summary>
 620:          public static void DeleteGeneralUse(string relative_path, int num)
 621:          {
 622:              string absolutePath;
 623:   
 624:              absolutePath = AbsolutePath();
 625:   
 626:              foreach (string file in Directory.GetFiles(absolutePath + relative_path, num + "_*.jpg"))
 627:              {
 628:                  System.IO.File.Delete(file);
 629:              }
 630:          }
 631:   
 632:          ////////////////////////////////////////////////////////////////////////////
 633:   
 634:          /// <summary>
 635:          ///
 636:          /// </summary>
 637:          public static void MoveGeneralUse(string relative_path, int num, int suffix_old, int suffix_new)
 638:          {
 639:              string name, name_new, absolutePath;
 640:   
 641:              absolutePath = AbsolutePath();
 642:   
 643:              if (num < 0 && suffix_old < 0)
 644:              {
 645:                  name = name_new = absolutePath + relative_path;
 646:              }
 647:              else if (num < 0)
 648:              {
 649:                  name = absolutePath + relative_path + "_" + suffix_old;
 650:                  name_new = absolutePath + relative_path + "_" + suffix_new;
 651:              }
 652:              else if (suffix_old < 0)
 653:              {
 654:                  name = name_new = absolutePath + relative_path + "_" + num;
 655:              }
 656:              else
 657:              {
 658:                  name = absolutePath + relative_path + num + "_" + suffix_old;
 659:                  name_new = absolutePath + relative_path + num + "_" + suffix_new;
 660:              }
 661:   
 662:              File.Move(name + "_vl.jpg", name_new + "_vl.jpg");
 663:              File.Move(name + "_l.jpg", name_new + "_l.jpg");
 664:              File.Move(name + "_m.jpg", name_new + "_m.jpg");
 665:              File.Move(name + "_s.jpg", name_new + "_s.jpg");
 666:              File.Move(name + "_t.jpg", name_new + "_t.jpg");
 667:              File.Move(name + ".jpg", name_new + ".jpg");
 668:   
 669:              File.Move(name + "_500.jpg", name_new + "_500.jpg");
 670:              File.Move(name + "_400.jpg", name_new + "_400.jpg");
 671:              File.Move(name + "_250.jpg", name_new + "_250.jpg");
 672:              File.Move(name + "_100.jpg", name_new + "_100.jpg");
 673:              File.Move(name + "_75.jpg", name_new + "_75.jpg");
 674:          }
 675:   
 676:          ////////////////////////////////////////////////////////////////////////////
 677:   
 678:          /// <summary>
 679:          ///
 680:          /// </summary>
 681:          public static int CountGeneralUse(string relative_path, int num)
 682:          {
 683:              int count;
 684:              string absolutePath, r;
 685:              string[] p;
 686:   
 687:              count = 0;
 688:              absolutePath = AbsolutePath();
 689:   
 690:              try
 691:              {
 692:                  // count images:
 693:                  p = Directory.GetFiles(absolutePath + relative_path, num + @"_*_t.jpg");
 694:   
 695:                  count = p.Length;
 696:              }
 697:              catch (Exception ex)
 698:              {
 699:  #if DEBUG
 700:                  r = "Error: " + ex.ToString();
 701:  #else
 702:                  r = "Error: " + ex.Message;
 703:  #endif
 704:              }
 705:              finally
 706:              {
 707:              }
 708:   
 709:              return count;
 710:          }
 711:   
 712:          ////////////////////////////////////////////////////////////////////////////
 713:   
 714:          /// <summary>
 715:          ///
 716:          /// </summary>
 717:          private static bool ThumbnailCallback()
 718:          {
 719:              return false;
 720:          }
 721:   
 722:  #if WFA
 723:  #else
 724:          ////////////////////////////////////////////////////////////////////////////
 725:          ////////////////////////////////////////////////////////////////////////////
 726:   
 727:          /// <summary>
 728:          ///
 729:          /// </summary>
 730:          public static string Default(string file)
 731:          {
 732:              string line;
 733:   
 734:              try
 735:              {
 736:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 737:                  line = "<img src=\"" + file + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" border=0>";
 738:                  image.Dispose();
 739:              }
 740:              catch
 741:              {
 742:                  line = ""; //"&nbsp;";
 743:              }
 744:   
 745:              return line;
 746:          }
 747:   
 748:          ////////////////////////////////////////////////////////////////////////////
 749:   
 750:          /// <summary>
 751:          ///
 752:          /// </summary>
 753:          public static string Url(string file, string url)
 754:          {
 755:              string line;
 756:   
 757:              try
 758:              {
 759:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 760:                  line = "<a href=" + url + "><img src=\"" + file + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" border=0></a>";
 761:                  image.Dispose();
 762:              }
 763:              catch
 764:              {
 765:                  line = ""; //"&nbsp;";
 766:              }
 767:   
 768:              return line;
 769:          }
 770:   
 771:          ////////////////////////////////////////////////////////////////////////////
 772:   
 773:          /// <summary>
 774:          ///
 775:          /// </summary>
 776:          public static string Shadowed(string file)
 777:          {
 778:              // produce an image with nice shadow for a ltr document:
 779:              string line;
 780:   
 781:              try
 782:              {
 783:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 784:   
 785:                  line = "<table cellpadding=0 cellspacing=0><tr><td><img src=\"" + file + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" border=0/></td><td width=5 height=5 valign=top background=image/shadow_ver_ltr.jpg><img src=image/shadow_ver_top_ltr.jpg width=5 height=5></td></tr><tr><td background=image/shadow_hor_ltr.jpg align=left><img src=image/shadow_hor_left_ltr.jpg width=5 height=5></td><td width=5 height=5><img src=image/shadow_corner_ltr.jpg width=5 height=5></td></tr></table>";
 786:   
 787:                  /*
 788:                  <table cellpadding="0" cellspacing="0">
 789:                   <tr>
 790:                    <td style="width:5px;height:5;vertical-align:top;background-image:url(../image/shadow_ver.jpg)"><img src="../image/shadow_ver_top.jpg" style="width:5px;height:5" alt=""></td>
 791:                    <td><asp:HyperLink id="photo_hl" runat="server"/></td>
 792:                   </tr>
 793:                   <tr>
 794:                    <td style="width:5px;height:5"><img src="../image/shadow_corner.jpg" style="width:5px;height:5" alt=""></td>
 795:                    <td style="text-align:right;background-image:url(../image/shadow_hor.jpg)"><img src="../image/shadow_hor_left.jpg" style="width:5px;height:5" alt=""></td>
 796:                   </tr>
 797:                  </table>
 798:  
 799:                  */
 800:   
 801:                  /*
 802:                  line = "<div id=\"image_shadowed\" style=\"position:relative\">"+
 803:                    "<img src=\""+file+"\" style=\"position:absolute:left:0px;top:0px;width:"+image.Width+"px;height:"+image.Height+"px\"/>"+
 804:                    "<img src=image/shadow_ver_top_ltr.jpg style=\"position:absolute;left:"+image.Width+"px;top:0px;width:5px;height:5px\"/>"+
 805:                    "<img style=\"position:absolute;left:"+image.Width+"px;top:5px;width:5px;height:"+(image.Height-5)+"px;background-image:url(image/shadow_ver_ltr.jpg)\"/>"+
 806:                    "<img src=image/shadow_hor_left_ltr.jpg style=\"position:absolute;left:0px;top:"+image.Height+"px;width:5px;height:5px\"/>"+
 807:                    "<img style=\"position:absolute;left:5px;top:"+image.Height+";width:"+(image.Width-5)+"px;height:5px;background-image:url(image/shadow_hor_ltr.jpg)\"/>"+
 808:                    "<img src=image/shadow_corner_ltr.jpg style=\"position:absolute;left:"+image.Width+"px;top:"+image.Height+"px;width:5px;height:5px\"/>"+
 809:                    "</div>";
 810:            
 811:                    */
 812:   
 813:                  image.Dispose();
 814:              }
 815:              catch
 816:              {
 817:                  line = ""; //"&nbsp;";
 818:              }
 819:   
 820:              return line;
 821:          }
 822:   
 823:          ////////////////////////////////////////////////////////////////////////////
 824:   
 825:          /// <summary>
 826:          /// Add shadows to image. This does not display well on Chrome
 827:          /// </summary>
 828:          public static string ShadowedUrl(System.Web.UI.Page page, string file, string url)
 829:          {
 830:              string line;
 831:   
 832:              try
 833:              {
 834:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 835:   
 836:                  line = "<table class=shadow cellpadding=0 cellspacing=0><tr><td><a href=" + url + "><img src=\"" + Ia.Cl.Model.Default.AbsolutePathUrl(page, file) + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" border=0/></a></td><td width=5 height=5 valign=top background=" + page.ResolveClientUrl("~/image/shadow_ver_ltr.jpg") + "><img src=" + page.ResolveClientUrl("~/image/shadow_ver_top_ltr.jpg") + " width=5 height=5></td></tr>" +
 837:                      "<tr><td background=" + page.ResolveClientUrl("~/image/shadow_horizontal.jpg") + " align=right><img src=" + page.ResolveClientUrl("~/image/shadow_hor_left_ltr.jpg") + " width=5 height=5></td><td width=5 height=5><img src=" + page.ResolveClientUrl("~/image/shadow_corner_ltr.jpg") + " width=5 height=5></td></tr></table>";
 838:   
 839:                  image.Dispose();
 840:              }
 841:              catch
 842:              {
 843:                  line = ""; //"&nbsp;";
 844:              }
 845:   
 846:              return line;
 847:          }
 848:   
 849:          ////////////////////////////////////////////////////////////////////////////
 850:   
 851:          /// <summary>
 852:          ///
 853:          /// </summary>
 854:          public static string TransparentPng(System.Web.UI.Page p, string file)
 855:          {
 856:              // produce div with a transparent PNG part showing
 857:              string line, imageUrl;
 858:   
 859:              imageUrl = Ia.Cl.Model.Default.AbsoluteUrl(p) + file;
 860:   
 861:              try
 862:              {
 863:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 864:                  line = "<div style=\"width:" + image.Width + ";height:" + image.Height + ";filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageUrl + "');\"><img src=\"" + imageUrl + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" style=\"filter:Alpha(opacity=0)\"/></div>";
 865:                  image.Dispose();
 866:              }
 867:              catch
 868:              {
 869:                  line = ""; //"&nbsp;";
 870:              }
 871:   
 872:              return line;
 873:          }
 874:   
 875:          ////////////////////////////////////////////////////////////////////////////
 876:   
 877:          /// <summary>
 878:          ///
 879:          /// </summary>
 880:          public static string TransparentPngShadowedUrl(System.Web.UI.Page p, string file, string navigate_url)
 881:          {
 882:              // produce div with a transparent PNG part showing and shadowed borders
 883:              string line, imageUrl;
 884:   
 885:              imageUrl = Ia.Cl.Model.Default.AbsoluteUrl(p) + file;
 886:   
 887:              try
 888:              {
 889:                  System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/" + file));
 890:                  line = "<div style=\"width:" + image.Width + ";height:" + image.Height + ";filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageUrl + "');\"><img src=\"" + imageUrl + "\" width=\"" + image.Width + "\" height=\"" + image.Height + "\" style=\"filter:Alpha(opacity=0)\"/></div>";
 891:                  line = "<table cellpadding=0 cellspacing=0><tr><td style=\"cursor:hand;\"><a href=" + navigate_url + ">" + line + " </a></td><td width=5 height=5 valign=top background=image/shadow_ver_ltr.jpg><img src=image/shadow_ver_top_ltr.jpg width=5 height=5></td></tr><tr><td background=image/shadow_hor_ltr.jpg align=left><img src=image/shadow_hor_left_ltr.jpg width=5 height=5></td><td width=5 height=5><img src=image/shadow_corner_ltr.jpg width=5 height=5></td></tr></table>";
 892:                  image.Dispose();
 893:              }
 894:              catch
 895:              {
 896:                  line = ""; //"&nbsp;";
 897:              }
 898:   
 899:              return line;
 900:          }
 901:  #endif
 902:   
 903:          ////////////////////////////////////////////////////////////////////////////
 904:   
 905:          /// <summary>
 906:          /// Compare two bitmap images and return true if they match
 907:          /// </summary>
 908:          public static bool Compare(Bitmap bmp1, Bitmap bmp2)
 909:          {
 910:              // http://www.codeproject.com/KB/GDI-plus/comparingimages.aspx
 911:   
 912:              bool b;
 913:   
 914:              b = true;
 915:   
 916:              // test to see if we have the same size of image
 917:              if (bmp1.Size != bmp2.Size) b = false;
 918:              else
 919:              {
 920:                  // convert each image to a byte array
 921:   
 922:                  System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();
 923:   
 924:                  byte[] btImage1 = new byte[1];
 925:                  btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
 926:   
 927:                  byte[] btImage2 = new byte[1];
 928:                  btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());
 929:   
 930:                  // compute a hash for each image
 931:                  SHA256Managed shaM = new SHA256Managed();
 932:                  byte[] hash1 = shaM.ComputeHash(btImage1);
 933:                  byte[] hash2 = shaM.ComputeHash(btImage2);
 934:   
 935:                  // compare the hash values
 936:                  for (int i = 0; i < hash1.Length && i < hash2.Length && b; i++) if (hash1[i] != hash2[i]) b = false;
 937:              }
 938:   
 939:              return b;
 940:          }
 941:   
 942:          ////////////////////////////////////////////////////////////////////////////
 943:   
 944:          /// <summary>
 945:          /// Check 
 946:          /// </summary>
 947:          private static string AbsolutePath(string relativeOrAbsolutePath)
 948:          {
 949:              string path;
 950:   
 951:              if (relativeOrAbsolutePath.Contains(":"))
 952:              {
 953:                  // this is an absolute path and we will return it
 954:                  path = relativeOrAbsolutePath;
 955:              }
 956:              else
 957:              {
 958:                  // this is a relative path and we will add to it the absolute path
 959:                  path = AbsolutePath() + relativeOrAbsolutePath;
 960:              }
 961:   
 962:              return path;
 963:          }
 964:   
 965:          ////////////////////////////////////////////////////////////////////////////
 966:   
 967:          /// <summary>
 968:          /// Return the absolute path
 969:          /// </summary>
 970:          private static string AbsolutePath()
 971:          {
 972:              string path;
 973:   
 974:  #if WFA
 975:              if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed) path = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory + @"\";
 976:              else path = AppDomain.CurrentDomain.BaseDirectory;
 977:  #else
 978:              path = AppDomain.CurrentDomain.BaseDirectory.ToString();
 979:  #endif
 980:   
 981:              return path;
 982:          }
 983:   
 984:          ////////////////////////////////////////////////////////////////////////////
 985:   
 986:          /// <summary>
 987:          ///
 988:          /// </summary>
 989:          public static Bitmap Resize(System.Drawing.Image image, int width, int height)
 990:          {
 991:              var destRect = new Rectangle(0, 0, width, height);
 992:              var destImage = new Bitmap(width, height);
 993:   
 994:              destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
 995:   
 996:              using (var graphics = Graphics.FromImage(destImage))
 997:              {
 998:                  graphics.CompositingMode = CompositingMode.SourceCopy;
 999:                  graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
 
                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                }
            }
 
            return destImage;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string ImageUrlDataFormat(Bitmap bitmap)
        {
            return string.Format("data:image/png;base64,{0}", Convert.ToBase64String(BitmapToBytes(bitmap)));
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static Byte[] BitmapToBytes(Bitmap bitmap)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
 
                return memoryStream.ToArray();
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
    }
}