C#双通道图像创建
所以,我正在构建一个控制台应用程序来生成2D柏林(ish)噪波,该噪波被分割到多个图像文件中。我使用的算法要求我分两次生成,一次为噪声创建种子,然后生成噪声。我将生成的噪声保存到生成种子的同一个文件中,以减少磁盘空间,并最终使其干净。但是我遇到了一个问题,在第二个过程中,我实际上无法访问该文件,因为它已经被另一个进程使用。下面是完整的代码,以查看是否有我遗漏的内容:C#双通道图像创建,c#,file,file-manipulation,C#,File,File Manipulation,所以,我正在构建一个控制台应用程序来生成2D柏林(ish)噪波,该噪波被分割到多个图像文件中。我使用的算法要求我分两次生成,一次为噪声创建种子,然后生成噪声。我将生成的噪声保存到生成种子的同一个文件中,以减少磁盘空间,并最终使其干净。但是我遇到了一个问题,在第二个过程中,我实际上无法访问该文件,因为它已经被另一个进程使用。下面是完整的代码,以查看是否有我遗漏的内容: using System; using System.Collections.Generic; using System.Comp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace MapGenerator
{
class Program
{
public static Random rng = new Random();
public static void Seed(int px, int py)
{
Bitmap seed = new Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
for (int x = 0; x < seed.Width; x++)
{
for (int y = 0; y < seed.Height; y++)
{
var val = rng.Next(0, 255);
seed.SetPixel(x, y, Color.FromArgb(255, val, val, val));
}
}
if (File.Exists("chunk," + (px - 1) + "," + (py) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px - 1) + "," + (py) + ".jpeg");
for (int y = 0; y < 256; y++)
{
seed.SetPixel(0, y, Color.FromArgb(255, source.GetPixel(255, y).R, source.GetPixel(255, y).G, source.GetPixel(255, y).B));
}
}
if (File.Exists("chunk," + (px + 1) + "," + (py) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px + 1) + "," + (py) + ".jpeg");
for (int y = 0; y < 256; y++)
{
seed.SetPixel(255, y, Color.FromArgb(255, source.GetPixel(0, y).R, source.GetPixel(0, y).G, source.GetPixel(0, y).B));
}
}
if (File.Exists("chunk," + (px) + "," + (py - 1) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px) + "," + (py - 1) + ".jpeg");
for (int x = 0; x < 256; x++)
{
seed.SetPixel(x, 0, Color.FromArgb(255, source.GetPixel(x, 255).R, source.GetPixel(x, 255).G, source.GetPixel(x, 255).B));
}
}
if (File.Exists("chunk," + (px) + "," + (py + 1) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px) + "," + (py + 1) + ".jpeg");
for (int x = 0; x < 256; x++)
{
seed.SetPixel(x, 255, Color.FromArgb(255, source.GetPixel(x, 0).R, source.GetPixel(x, 0).G, source.GetPixel(x, 0).B));
}
}
seed.Save("chunk," + px + "," + py + ".jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
seed.Dispose();
}
public static void Perlin(int px, int py)
{
Bitmap seed = new Bitmap("chunk," + px + "," + py + ".jpeg");
Bitmap output = new Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
for (int y = 0; y < 256; y++)
{
for (int x = 0; x < 256; x++)
{
double noise = 0.0;
double scale = 1.0;
double acc = 0.0;
for (int o = 0; o < 8; o++)
{
int pitch = 256 >> o;
int sampleX1 = (x / pitch) * pitch;
int sampleY1 = (y / pitch) * pitch;
int sampleX2 = (sampleX1 + pitch);
int sampleY2 = (sampleY1 + pitch);
sampleX2 = (sampleX2 == 256) ? 255 : sampleX2;
sampleY2 = (sampleY2 == 256) ? 255 : sampleY2;
double Xblend = (double)(x - sampleX1) / (double)pitch;
double Yblend = (double)(y - sampleY1) / (double)pitch;
// interpolate between the two points
double Tsample = ((1 - Xblend) * ((double)seed.GetPixel(sampleX1, sampleY1).R / 255.0)) + (Xblend * ((double)seed.GetPixel(sampleX2, sampleY1).R / 255.0));
double Bsample = ((1 - Xblend) * ((double)seed.GetPixel(sampleX1, sampleY2).R / 255.0)) + (Xblend * ((double)seed.GetPixel(sampleX2, sampleY2).R / 255.0));
noise += (((1 - Yblend) * Tsample) + (Yblend * Bsample)) * scale;
acc += scale;
scale = scale * 0.6;
}
noise = noise / acc;
noise = noise * 255.0;
output.SetPixel(x, y, Color.FromArgb(255, (int)(noise), (int)(noise), (int)(noise)));
}
}
seed.Dispose();
File.Delete("chunk," + px + "," + py + ".jpeg");
output.Save("chunk," + px + "," + py + ".jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
output.Dispose();
}
static void Main(string[] args)
{
int depth = 1;
for(int x = -depth; x <= depth; x++)
{
for(int y = -depth; y <= depth; y++)
{
Seed(x, y);
}
}
for (int x = -depth; x <= depth; x++)
{
for (int y = -depth; y <= depth; y++)
{
Perlin(x, y);
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.IO;
命名空间映射生成器
{
班级计划
{
公共静态随机rng=新随机();
公共静态无效种子(int-px,int-py)
{
位图种子=新位图(256,256,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
对于(int x=0;x>o;
int sampleX1=(x/音高)*音高;
int sampleY1=(y/音高)*音高;
int sampleX2=(sampleX1+音高);
int sampleY2=(sampleY1+音高);
sampleX2=(sampleX2==256)?255:sampleX2;
sampleY2=(sampleY2==256)?255:sampleY2;
双音高=(双音高)(x-sampleX1)/(双音高);
双Yblend=(双)(y-样本1)/(双)音高;
//在两点之间插值
double-Tsample=((1-Xblend)*((double)seed.GetPixel(sampleX1,sampleY1.R/255.0))+(Xblend*((double)seed.GetPixel(sampleX2,sampleY1.R/255.0));
double-Bsample=((1-Xblend)*((double)seed.GetPixel(sampleX1,sampleY2.R/255.0))+(Xblend*((double)seed.GetPixel(sampleX2,sampleY2.R/255.0));
噪声+=((1-Yblend)*Tsample)+(Yblend*Bsample))*标度;
acc+=量表;
比例=比例*0.6;
}
噪音=噪音/acc;
噪声=噪声*255.0;
输出.SetPixel(x,y,Color.FromArgb(255,(int)(noise),(int)(noise),(int)(noise),(int)(noise));
}
}
种子;
删除(“chunk,“+px+”,“+py+”.jpeg”);
输出.保存(“chunk,“+px+”,“+py+”.jpeg”,System.Drawing.Imaging.ImageFormat.jpeg);
output.Dispose();
}
静态void Main(字符串[]参数)
{
int深度=1;
对于(intx=-depth;x您需要处理位图,如下所示
另外,我将使用Lockbits
而不是GetPixel
和SetPixel
,您将获得更好的性能
public static void Seed(int px, int py)
{
using (var seed = new Bitmap(256, 256, PixelFormat.Format24bppRgb))
{
for (var x = 0; x < seed.Width; x++)
for (var y = 0; y < seed.Height; y++)
{
var val = rng.Next(0, 255);
seed.SetPixel(x, y, Color.FromArgb(255, val, val, val));
}
if (File.Exists("chunk," + (px - 1) + "," + py + ".jpeg"))
using (var source = new Bitmap("chunk," + (px - 1) + "," + py + ".jpeg"))
for (var y = 0; y < 256; y++)
seed.SetPixel(0, y, Color.FromArgb(255, source.GetPixel(255, y).R, source.GetPixel(255, y).G, source.GetPixel(255, y).B));
if (File.Exists("chunk," + (px + 1) + "," + py + ".jpeg"))
using (var source = new Bitmap("chunk," + (px + 1) + "," + py + ".jpeg"))
for (var y = 0; y < 256; y++)
seed.SetPixel(255, y, Color.FromArgb(255, source.GetPixel(0, y).R, source.GetPixel(0, y).G, source.GetPixel(0, y).B));
if (File.Exists("chunk," + px + "," + (py - 1) + ".jpeg"))
using (var source = new Bitmap("chunk," + px + "," + (py - 1) + ".jpeg"))
for (var x = 0; x < 256; x++)
seed.SetPixel(x, 0, Color.FromArgb(255, source.GetPixel(x, 255).R, source.GetPixel(x, 255).G, source.GetPixel(x, 255).B));
if (File.Exists("chunk," + px + "," + (py + 1) + ".jpeg"))
using (var source = new Bitmap("chunk," + px + "," + (py + 1) + ".jpeg"))
for (var x = 0; x < 256; x++)
seed.SetPixel(x, 255, Color.FromArgb(255, source.GetPixel(x, 0).R, source.GetPixel(x, 0).G, source.GetPixel(x, 0).B));
seed.Save("chunk," + px + "," + py + ".jpeg", ImageFormat.Jpeg);
}
}
if(File.Exists(“chunk,”+(px-1)+“,”+(py)+“.jpeg”))
{
位图源=新位图(“块,”+(px-1)+“,”+(py)+“.jpeg”);
对于(int y=0;y<256;y++)
{
seed.SetPixel(0,y,Color.FromArgb(255,source.GetPixel(255,y).R,source.GetPixel(255,y).G,source.GetPixel(255,y.B));
}
source.Dispose();
}
如果(File.Exists(“chunk,”+(px+1)+“,”+(py)+“.jpeg”))
{
位图源=新位图(“块,”+(px+1)+“,”+(py)+“.jpeg”);
对于(int y=0;y<256;y++)
{
seed.SetPixel(255,y,Color.FromArgb(255,source.GetPixel(0,y).R,source.GetPixel(0,y)
using (var seed = new Bitmap(256, 256, PixelFormat.Format24bppRgb))
{
// lock the array for direct access
var bitmapData = seed.LockBits(new Rectangle(0,0,seed.Width,seed.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
// get the pointer
var scan0Ptr = (int*)bitmapData.Scan0;
// get the stride
var stride = bitmapData.Stride / 4;
for (var x = 0; x < seed.Width; x++)
for (var y = 0; y < seed.Height; y++)
{
var val = rng.Next(0, 255);
*(scan0Ptr + x + y * stride) = Color.FromArgb(255, val, val, val).ToArgb();
}
seed.UnlockBits(bitmapData);
...
if (File.Exists("chunk," + (px - 1) + "," + (py) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px - 1) + "," + (py) + ".jpeg");
for (int y = 0; y < 256; y++)
{
seed.SetPixel(0, y, Color.FromArgb(255, source.GetPixel(255, y).R, source.GetPixel(255, y).G, source.GetPixel(255, y).B));
}
source.Dispose();
}
if (File.Exists("chunk," + (px + 1) + "," + (py) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px + 1) + "," + (py) + ".jpeg");
for (int y = 0; y < 256; y++)
{
seed.SetPixel(255, y, Color.FromArgb(255, source.GetPixel(0, y).R, source.GetPixel(0, y).G, source.GetPixel(0, y).B));
}
source.Dispose();
}
if (File.Exists("chunk," + (px) + "," + (py - 1) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px) + "," + (py - 1) + ".jpeg");
for (int x = 0; x < 256; x++)
{
seed.SetPixel(x, 0, Color.FromArgb(255, source.GetPixel(x, 255).R, source.GetPixel(x, 255).G, source.GetPixel(x, 255).B));
}
source.Dispose();
}
if (File.Exists("chunk," + (px) + "," + (py + 1) + ".jpeg"))
{
Bitmap source = new Bitmap("chunk," + (px) + "," + (py + 1) + ".jpeg");
for (int x = 0; x < 256; x++)
{
seed.SetPixel(x, 255, Color.FromArgb(255, source.GetPixel(x, 0).R, source.GetPixel(x, 0).G, source.GetPixel(x, 0).B));
}
source.Dispose();
}