将sgy文件转成png,C#的代码可以运行,希望懂C#和java的同志们帮忙转成java代码,感激不尽!
using System.Drawing;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
byte[] MyData = new byte[0];
//创建文件流的实例
FileStream fileStream = new FileStream("D:\\environment\\idea\\json\\test-file\\sgy\\ss.sgy", FileMode.Open);
BinaryReader binaryReader1 = new BinaryReader(fileStream);
BinaryReader binaryReader2 = new BinaryReader(fileStream, Encoding.UTF8);
BinaryReader binaryReader3 = new BinaryReader(fileStream, Encoding.UTF8, true);
MyData = ReadHeadAndCreateImage(binaryReader3, 0, 1, 5, 20, 181, 185, 189, 193);
MemoryStream ms = new MemoryStream(MyData);
File.WriteAllBytes("D:\\environment\\idea\\json\\test-file\\sgy\\image.png", MyData);
Console.WriteLine("图片写入完成!");
Console.ReadKey();
}
///
/// 读取二进制SEGY文件,并生成IMAGE反回二进制数据,segy定义
///
/// <param name="reader"></param>
/// <param name="startTime">起始时间毫秒</param>
/// <param name="amplitude"></param>
/// <param name="trace"></param>
/// <param name="timeScaling"></param>
/// <returns></returns>
private static Byte[] ReadHeadAndCreateImage(BinaryReader reader, int startTime, float amplitude, int trace, int timeScaling, int HZB, int ZZB, int L, int T)
{
byte[] b = new byte[2];
byte[] buffer;
//跳过3600字节的卷头
buffer = reader.ReadBytes(3600);
b[0] = buffer[3217];
b[1] = buffer[3216];
int m_nTime = System.BitConverter.ToUInt16(b, 0);
b[0] = buffer[3221];
b[1] = buffer[3220];
int m_nFrequency = BitConverter.ToUInt16(b, 0);
b[0] = buffer[3225];
b[1] = buffer[3224];
int m_nCode = BitConverter.ToUInt16(b, 0);
buffer = reader.ReadBytes(2);
int m_nstartTrack = BitConverter.ToUInt16(buffer, 0);
int m_nEndTrack;
if (m_nCode.Equals(3))
{
m_nEndTrack = Convert.ToInt32((reader.BaseStream.Length - 3600) / (240 + m_nFrequency * 4));
}
else
{
m_nEndTrack = Convert.ToInt32((reader.BaseStream.Length - 3600) / (240 + m_nFrequency * 4));
}
//读算图形大小
float LeftMargin = 3; //左侧、右侧预留位置
float TopMargin = 3; //上侧预留位置
float traceWidth = (m_nEndTrack - m_nstartTrack) * 1.0f / trace; //总道宽度
float traceHeight = ((m_nTime * m_nFrequency) / 1000000.0f) * timeScaling; //道高度以少为单位计算,将微秒转为秒
int imageWidth = MillimeterConvertPixel(traceWidth + LeftMargin * 2) * 10; //计算的图形宽度
int imageHeight = MillimeterConvertPixel(traceHeight + TopMargin) * 10; //计算的图形高度
float xstep = 10.0f / trace; // X方向步长
float ystep = (m_nTime * timeScaling * 10.0f) / 1000000;
Console.WriteLine(imageWidth + ":" + imageHeight);
Bitmap bitmap = new Bitmap(imageWidth, imageHeight);
Graphics g = Graphics.FromImage(bitmap);
g.PageUnit = GraphicsUnit.Millimeter;
g.Clear(Color.White);
#region 绘制地震剖面
//当前填充
List<PointF> fill = new List<PointF>();
PointF SP = new PointF();
PointF EP = new PointF();
byte[] b4 = new byte[4];
double value = 0;
int X, Y;
int L1 = 0;
int T1 = 0;
reader.BaseStream.Seek(3600, SeekOrigin.Begin);
for (int i = 0; i < m_nEndTrack; i++)
{
//跳过240字节的道头
buffer = reader.ReadBytes(240);
if (L != -1)
{
b4[0] = buffer[L + 2];
b4[1] = buffer[L + 1];
b4[2] = buffer[L];
b4[3] = buffer[L - 1];
L1 = BitConverter.ToInt32(b4, 0);
}
if (T != -1)
{
b4[0] = buffer[T + 2];
b4[1] = buffer[T + 1];
b4[2] = buffer[T];
b4[3] = buffer[T - 1];
T1 = BitConverter.ToInt32(b4, 0);
}
b4[0] = buffer[HZB + 2];
b4[1] = buffer[HZB + 1];
b4[2] = buffer[HZB];
b4[3] = buffer[HZB - 1];
X = Convert.ToInt32(As_Traces(BitConverter.ToInt32(b4, 0).ToString(), 1));
b4[0] = buffer[ZZB + 2];
b4[1] = buffer[ZZB + 1];
b4[2] = buffer[ZZB];
b4[3] = buffer[ZZB - 1];
Y = Convert.ToInt32(As_Traces(BitConverter.ToInt32(b4, 0).ToString(), 2));
if (m_nCode.Equals(1))
{
Console.WriteLine(Convert.ToInt32(reader.BaseStream.Length));
buffer = reader.ReadBytes(4 * m_nFrequency);
Console.WriteLine(Convert.ToInt32(reader.BaseStream.Length));
List<double> values = new List<double>();
for (int j = 0; j < buffer.Length; j = j + 4)
{
b4[3] = buffer[j + 0];
b4[2] = buffer[j + 1];
b4[1] = buffer[j + 2];
b4[0] = buffer[j + 3];
value = BitConverter.ToUInt32(b4, 0);
if (value != 0)
{
value = IBMtoIEE(BitConverter.ToUInt32(b4, 0));
}
values.Add(value);
}
double max = values.Max(xx => Math.Abs(xx));//计算最大幅度值
List<PointF> pps = new List<PointF>(); //绘图每道点列表
int index = 0;
int time = 0;
foreach (double d in values)
{
//将字符串转换为Float类型
float ppsX = Convert.ToSingle(LeftMargin * 10 + xstep * (i + 1) + xstep * (d / max) * amplitude);
float ppsY = TopMargin * 10 + index * ystep;
PointF pointF = new PointF(ppsX, ppsY);
pps.Add(pointF);
//计算时间刻度
time = ((m_nTime / 1000) * index) + startTime;
if (time % 500 == 0 && index > 0)
{
//左侧刻度线
g.DrawLine(new Pen(Color.Black, 1f), 20, TopMargin * 10 + index * ystep, 30, TopMargin * 10 + index * ystep);
//左侧文本
g.DrawString(time.ToString(), new Font("宋体", 15.0f), new SolidBrush(Color.Black), 1 * 10 - 1.5f, TopMargin * 10 + index * ystep - 3);
//右侧线
g.DrawLine(new Pen(Color.Black, 1f), traceWidth * 10 + LeftMargin * 10, TopMargin * 10 + index * ystep, traceWidth * 10 + LeftMargin * 10 + 10, TopMargin * 10 + index * ystep);
//右侧文本
g.DrawString(time.ToString(), new Font("宋体", 15.0f), new SolidBrush(Color.Black), traceWidth * 10 + LeftMargin * 10 + 10, TopMargin * 10 + index * ystep - 3);
}
else if (time % 100 == 0)
{
g.DrawLine(new Pen(Color.Black, 1f), 25, TopMargin * 10 + index * ystep, 30, TopMargin * 10 + index * ystep);
g.DrawLine(new Pen(Color.Black, 1f), traceWidth * 10 + LeftMargin * 10, TopMargin * 10 + index * ystep, traceWidth * 10 + LeftMargin * 10 + 5, TopMargin * 10 + index * ystep);
}
index++;
}
SP = new PointF(LeftMargin * 10 + xstep * (i + 1), 0);
EP = new PointF(LeftMargin * 10 + xstep * (i + 1), TopMargin * 10 + index * ystep);
//显示刻度线
if ((i + 1) % 10 == 0)
{
if ((i + 1) % 50 == 0)
{
g.DrawLine(new Pen(Color.Black, 1f), SP.X, 20, SP.X, 30);
if (L != -1)
{
g.DrawString("L" + L1, new Font("宋体", 14.0f), new SolidBrush(Color.Black), SP.X - 5, 10);
}
if (T != -1)
{
g.DrawString("T" + T1, new Font("宋体", 14.0f), new SolidBrush(Color.Black), SP.X - 5, 15);
}
}
else
{
g.DrawLine(new Pen(Color.Black, 1f), SP.X, 25, SP.X, 30);
}
}
//填充列表
List<List<PointF>> FillList = new List<List<PointF>>();
//填充
FillList.Clear();
bool SR = true;
PointF p1, p2;
fill = new List<PointF>();
for (int s = 0; s < pps.Count - 1; s++)
{
p1 = pps[s];
p2 = pps[s + 1];
if (p1.X <= SP.X && p2.X > SP.X)
{
fill = new List<PointF>();
PointF inter = new PointF();
GetIntersection(p1, p2, SP, EP, ref inter);
fill.Add(inter);
//添加交点与P2点
fill.Add(p2);
SR = true;
}
else if (p1.X > SP.X && p2.X > SP.X)
{
if (SR)
{
fill.Add(p1);
fill.Add(p2);
}
}
else if (p1.X > SP.X && p2.X <= SP.X)
{
if (SR)
{
//添加P1与交点
fill.Add(p1);
PointF inter = new PointF();
GetIntersection(p1, p2, SP, EP, ref inter);
fill.Add(inter);
FillList.Add(fill);
SR = false;
}
}
else if (p1.X == SP.X && p2.X == SP.X)
{
if (SR && s == pps.Count - 2)
{
FillList.Add(fill);
}
}
else if (p1.X < SP.X && p2.X < SP.X)
{
if (SR && s == pps.Count - 2)
{
FillList.Add(fill);
}
}
if (SR && s == pps.Count - 2)
{
FillList.Add(fill);
}
}
using (SolidBrush brush = new SolidBrush(Color.Black))
{
foreach (List<PointF> px in FillList)
{
g.FillPolygon(brush, px.ToArray());
/*g.DrawPolygon(new Pen(Color.Black, 1f), px.ToArray());*/
}
}
g.DrawLines(new Pen(Color.Black, 0.0001f), pps.ToArray());
}
else if (m_nCode.Equals(2))
{
buffer = reader.ReadBytes(4 * m_nFrequency);
}
else if (m_nCode.Equals(3))
{
buffer = reader.ReadBytes(2 * m_nFrequency);
}
else if (m_nCode.Equals(4))
{
buffer = reader.ReadBytes(4 * m_nFrequency);
}
}
g.Dispose();
//将Bitmap转为byte[]
MemoryStream ms = new MemoryStream();
// Save to memory using the Jpeg format
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] bmpBytes = ms.GetBuffer();
bitmap.Dispose();
ms.Close();
return bmpBytes;
}
///
/// 把毫米换算成像素
///
/// <param name="Millimeter">多少毫米</param>
/// <returns>多少像素</returns>
public static int MillimeterConvertPixel(float Millimeter)
{
return ((int)(Millimeter / 25.4 * 96));
}
///
///
///
/// <param name="all"></param>
/// <param name="type"></param>
/// <returns></returns>
public static string As_Traces(string all, int type)
{
string as_traces = all;
if (all.Length < 6) return all;
if (type == 1)
{
if (all.Substring(0, 2) != "20") all = "20" + all;
return all.Substring(0, 8);
}
if (type == 2)
{
if (all.Substring(0, 1) != "4") all = "4" + all;
return all.Substring(0, 7);
}
return as_traces;
}
///
/// 数值转换参数
///
/// <param name="DataUint32"></param>
/// <returns></returns>
private static double IBMtoIEE(UInt32 DataUint32)
{
//符号位
int sign = (int)(DataUint32 >> 31);
//7位指数
// gain exponent from first byte, last 7 bits
double exp0 = (double)((DataUint32 & 0x7f000000) >> 24);
// 去除基数
double exp = (double)(exp0 - 64);
// gain mantissa from last 3 bytes
double frac = (double)(DataUint32 & 0x00ffffff);
double fmant = frac / (Math.Pow(2, 24));
return (1 - 2 * sign) * (Math.Pow(16, exp)) * fmant;
}
///
/// 计算线段交点
///
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="d"></param>
/// <param name="intersection"></param>
private static void GetIntersection(PointF a, PointF b, PointF c, PointF d, ref PointF intersection)
{
intersection.X = ((b.X - a.X) * (c.X - d.X) * (c.Y - a.Y) - c.X * (b.X - a.X) * (c.Y - d.Y) + a.X * (b.Y - a.Y) * (c.X - d.X)) / ((b.Y - a.Y) * (c.X - d.X) - (b.X - a.X) * (c.Y - d.Y));
intersection.Y = ((b.Y - a.Y) * (c.Y - d.Y) * (c.X - a.X) - c.Y * (b.Y - a.Y) * (c.X - d.X) + a.Y * (b.X - a.X) * (c.Y - d.Y)) / ((b.X - a.X) * (c.Y - d.Y) - (b.Y - a.Y) * (c.X - d.X));
}
#endregion
}
}