C#の コンソールアプリケーション(.NET Framework) で作成
namespaceの部分はプロジェクト名に変える
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace (ここ変えて)
{
internal class Program
{
public class ColorData
{
public string path;
public byte r;
public byte g;
public byte b;
public double sL = 0;
public double sa = 0;
public double sb = 0;
public int use = 0;
public ColorData(string path,byte r, byte g, byte b)
{
this.path = path;
this.r = r;
this.g = g;
this.b = b;
}
public ColorData(string path, double sL, double sa, double sb)
{
this.path = path;
this.sL = sL;
this.sa = sa;
this.sb = sb;
}
}
static List colors = new List();
static double Lin(double x)
{
return (x < 0.04045) ? x / 12.92 : Math.Pow((x + 0.055) / 1.055, 2.4);
}
static double[] XYZ(double r,double g,double b)
{
r = Lin(r / 255.0);
g = Lin(g / 255.0);
b = Lin(b / 255.0);
return new double[] {(0.4124 * r + 0.3576 * g + 0.1805 * b) / 0.9505,
0.2126 * r + 0.7152 * g + 0.0722 * b,
(0.0193 * r + 0.1192 * g + 0.9505 * b) / 1.089};
}
static double[] Lab(double x, double y, double z)
{
double[] rt = { 0, 0, 0 };
rt[0] = Labf(y);
rt[1] = 4.3103 * (Labf(x) - Labf(y));
rt[2] = 1.7241 * (Labf(y) - Labf(z));
return rt;
}
static double Labf(double x)
{
return (x > 0.008856) ? 116 * Math.Pow(x, 0.333) - 16 : 903.296 * x;
}
static void Main(string[] args)
{
//ここに後述するコードを挿入
Console.ReadLine();
}
static void MakeData(string name, string path, int mult_read_pixel)
{
DirectoryInfo di = new DirectoryInfo(path);
string[] ext = { "*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG" };
foreach (string ex in ext)
{
FileInfo[] fiAlls = di.GetFiles(ex, SearchOption.AllDirectories);
for (int i = 0; i < fiAlls.Length; i++)
{
Bitmap bitmap2 = new Bitmap(fiAlls[i].FullName);
Bitmap bitmap = new Bitmap(bitmap2, new Size((int)(1.0 * bitmap2.Width / mult_read_pixel), (int)(1.0 * bitmap2.Height / mult_read_pixel)));
bitmap2.Dispose();
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpdata = bitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
try
{
byte[] imgdata = new byte[bmpdata.Stride * bitmap.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, imgdata, 0, imgdata.Length);
double[] _rgb = { 0, 0, 0 };
for (int y = 0; y < bitmap.Height; ++y)
{
for (int x = 0; x < bitmap.Width; ++x)
{
int pos = y * bmpdata.Stride + x * 4; //Format32bppArgbは1ピクセル4バイト
_rgb[2] += 1.0 * imgdata[pos] / (bitmap.Height * bitmap.Width);
_rgb[1] += 1.0 * imgdata[pos + 1] / (bitmap.Height * bitmap.Width);
_rgb[0] += 1.0 * imgdata[pos + 2] / (bitmap.Height * bitmap.Width);
}
}
colors.Add(new ColorData(fiAlls[i].FullName, (byte)_rgb[0], (byte)_rgb[1], (byte)_rgb[2]));
}
finally
{
bitmap.UnlockBits(bmpdata);
}
bitmap.Dispose();
Console.WriteLine(ex + ": " + i + "/" + (fiAlls.Length - 1));
}
}
FileStream fs = new FileStream(name + ".dat", FileMode.Create);
BinaryWriter writer = new BinaryWriter(fs);
for (int i = 0; i < colors.Count; ++i)
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(colors[i].path);
byte[] rgb = { colors[i].r, colors[i].g, colors[i].b };
writer.Write((byte)data.Length);
writer.Write(data);
writer.Write(rgb);
}
writer.Close();
fs.Close();
colors.Clear();
Console.WriteLine("Finish");
}
static void MakePicture(string name,string pic_path,string data_path,int mult_base_p,int mult_use_p)
{
int[] wh = { -1, -1 };
int[] rwh = { -1, -1 };
Bitmap canvas = new Bitmap(1,1);
Graphics g = Graphics.FromImage(canvas);
using (var fs = File.OpenRead(data_path + ".dat"))
{
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int)fs.Length);
int k = 0;
while (k < fs.Length)
{
byte[] pb = new byte[bytes[k]];
k++;
for(int j = 0; j < pb.Length; j++)
{
pb[j] = bytes[k + j];
}
string fn = System.Text.Encoding.UTF8.GetString(pb);
k += pb.Length;
double[] xyz = XYZ(bytes[k], bytes[k + 1], bytes[k + 2]);
double[] clab = Lab(xyz[0], xyz[1], xyz[2]);
colors.Add(new ColorData(fn, clab[0], clab[1], clab[2]));
k += 3;
}
}
Image img = Image.FromFile(pic_path);
Bitmap imgbitmap = new Bitmap(img);
Bitmap bitmap = new Bitmap(imgbitmap, new Size((int)(1.0 * img.Width / mult_base_p), (int)(1.0 * img.Height / mult_base_p)));
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpdata = bitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
try
{
byte[] imgdata = new byte[bmpdata.Stride * bitmap.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, imgdata, 0, imgdata.Length);
for (int y = 0; y < bitmap.Height; ++y)
{
for (int x = 0; x < bitmap.Width; ++x)
{
int pos = y * bmpdata.Stride + x * 4;
int[] select = { 0, 999 };
double min_v = 9999999;
for (int i = 0; i < colors.Count; i++)
{
double[] xyz = XYZ(imgdata[pos + 2], imgdata[pos + 1], imgdata[pos]);
double[] lab = Lab(xyz[0], xyz[1], xyz[2]);
double[] delta = { lab[0] - colors[i].sL, lab[1] - colors[i].sa, lab[2] - colors[i].sb };
double tmp = delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
if(tmp < min_v && colors[i].use < select[1])
{
select[0] = i;
min_v = tmp;
select[1] = colors[i].use;
}
}
Bitmap srcImage2 = new Bitmap(colors[select[0]].path);
if (rwh[0] == -1)
{
rwh[0] = (int)(1.0 * srcImage2.Width / mult_use_p);
rwh[1] = (int)(1.0 * srcImage2.Height / mult_use_p);
}
Bitmap srcImage3 = new Bitmap(srcImage2, new Size(rwh[0], rwh[1]));
Rectangle urect = srcImage3.Width > srcImage3.Height ? new Rectangle((srcImage3.Width - srcImage3.Height) / 2, 0, srcImage3.Height, srcImage3.Height) : new Rectangle((srcImage3.Height - srcImage3.Width) / 2, 0, srcImage3.Width, srcImage3.Width);
Bitmap srcImage = srcImage3.Clone(urect, srcImage3.PixelFormat);
srcImage2.Dispose();
srcImage3.Dispose();
if (wh[0] == -1)
{
wh[0] = bitmap.Width * srcImage.Width;
wh[1] = bitmap.Height * srcImage.Height;
canvas = new Bitmap(wh[0], wh[1]);
g = Graphics.FromImage(canvas);
}
g.DrawImage(srcImage, new Point(srcImage.Width * x,srcImage.Height * y));
colors[select[0]].use++;
srcImage.Dispose();
}
Console.WriteLine(y + "/" + (bitmap.Height - 1));
}
}
finally
{
bitmap.UnlockBits(bmpdata);
}
canvas.Save(AppDomain.CurrentDomain.BaseDirectory + name + ".png", System.Drawing.Imaging.ImageFormat.Png);
colors.Clear();
g.Dispose();
imgbitmap.Dispose();
bitmap.Dispose();
Console.WriteLine("Finish");
}
}
}