Skip to content

Instantly share code, notes, and snippets.

@eldewall
Created January 10, 2013 09:57
Show Gist options
  • Save eldewall/4500879 to your computer and use it in GitHub Desktop.
Save eldewall/4500879 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NovusDataLayer.Classes;
using data = NovusDataLayer.DataClasses;
using System.Drawing;
using System.Diagnostics;
using System.IO;
using System.Drawing.Imaging;
namespace Api.Classes.Images.refactor {
public class ImageSpecification {
public static int DefaultQuality = 85;
public static int DefaultSharpen = 70;
public int Sharpen { get; private set; }
public int Quality { get; private set; }
public int Height { get; private set; }
public int Width { get; private set; }
public ImageSpecification(string forSize) {
Set(forSize);
}
private void Set(string size) {
Quality = DefaultQuality;
Sharpen = DefaultSharpen;
switch (size.ToLower()) {
case "adminthumb":
Height = 0;
Width = 180;
break;
case "adminaccount":
Height = 100;
Width = 100;
break;
case "adminlogo":
Height = 80;
Width = 180;
break;
default:
throw new NotImplementedException("No spec defined for size: " + size);
}
}
public void NormalizeHeight(double ratio) {
Height = (int)Math.Round(Width * ratio);
}
}
public class Timings {
public double Load { get; private set; }
public double Resize { get; private set; }
public double Rotate { get; private set; }
public double Create { get; private set; }
public double Sharpen {get; private set;}
public Timings(double load, double resize, double rotate, double create, double sharpen) {
Load = load;
Resize = resize;
Rotate = rotate;
Create = create;
Sharpen = sharpen;
}
}
public class ImageCreationResult {
public byte[] ImageBytes { get; private set; }
public Timings Timings { get; private set; }
public ImageCreationResult(byte[] imageBytes, Timings timings) {
ImageBytes = imageBytes;
Timings = timings;
}
}
public class ImageCreator {
public data.Image Original { get; private set; }
public ImageSpecification Spec { get; private set; }
public ImageCreator(data.Image original, ImageSpecification spec) {
Original = original;
Spec = spec;
}
private Bitmap Load() {
return (Bitmap)Image.FromFile(Original.FullPath);
}
private Bitmap Resize(Bitmap source) {
return (Bitmap)ImageTools.Resize(source, Color.White, Spec.Width, Spec.Height, 1.0);
}
private void Rotate(Bitmap image) {
if (Original.Angle.Value != 0) {
RotateFlipType type;
switch (Original.Angle.Value) {
case 1:
type = RotateFlipType.Rotate90FlipNone;
break;
case 2:
type = RotateFlipType.Rotate180FlipNone;
break;
case 3:
type = RotateFlipType.Rotate270FlipNone;
break;
default:
throw new NotImplementedException();
}
image.RotateFlip(type);
}
}
public ImageCreationResult Create() {
double load, resize, rotate = 0, create, sharpen;
byte[] imageBytes = null;
using (Bitmap source = Time(() => { return Load(); }, out load)) {
using (Bitmap result = Time(() => { return Resize(source); }, out resize)) {
Time(() => {
Rotate(result);
}, out rotate);
Time(() => {
ImageTools.Sharpen(result, Spec.Sharpen, false);
}, out sharpen);
Time(() => {
imageBytes = ImageTools.CreateJpeg(result, Spec.Quality);
}, out create);
}
}
Timings t = new Timings(load, resize, rotate, create, sharpen);
return new ImageCreationResult(imageBytes, t);
}
public static byte[] ImageMessage(string message) {
using (Bitmap image = new Bitmap(500, 200)) {
using (Graphics g = Graphics.FromImage(image)) {
g.Clear(Color.White);
using (Font font = new Font("Arial", 10)) {
g.DrawString(message, font, Brushes.Black, 5, 5);
}
}
using (MemoryStream m = new MemoryStream()) {
image.Save(m, ImageFormat.Jpeg);
return m.ToArray();
}
}
}
private T Time<T>(Func<T> func, out double timing) {
Stopwatch sw = Stopwatch.StartNew();
T r = func();
sw.Stop();
timing = Math.Round(1000.0 * (double)sw.ElapsedTicks / (double)Stopwatch.Frequency, 3);
return r;
}
private void Time(Action action, out double timing) {
Stopwatch sw = Stopwatch.StartNew();
action();
sw.Stop();
timing = Math.Round(1000.0 * (double)sw.ElapsedTicks / (double)Stopwatch.Frequency, 3);
}
}
public class ImageStore {
public byte[] Get(UserIdentity user, int imageId, string size) {
ImageCreator creator = null;
ImageCreationResult result = null;
using (ConnectionProvider db = new ConnectionProvider()) {
Result<data.Image> imageResult = data.Image.Get(user, db, imageId);
if (imageResult.Ok) {
data.Image img = imageResult.Value;
var spec = new ImageSpecification(size);
if (spec.Height == 0) {
spec.NormalizeHeight(img.Height / img.Width);
}
creator = new ImageCreator(img, spec);
result = creator.Create();
return result.ImageBytes;
} else {
return ImageCreator.ImageMessage(imageResult.GetErrors());
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment