using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
namespace GlobeMaker
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private AxPAJANTLib.AxPajantImageCtrl axPajantImageCtrl1;
private System.Windows.Forms.Button OutputFileButton;
private System.Windows.Forms.NumericUpDown OutputImageWidthCtrl;
private System.Windows.Forms.Button InputFileButton;
private System.Windows.Forms.NumericUpDown OutputImageHeightCtrl;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Button DismissButton;
private System.Windows.Forms.Button RunButton;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.NumericUpDown NumberOfGoresCtrl;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.NumericUpDown OverlapGoresByCtrl;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.axPajantImageCtrl1 = new AxPAJANTLib.AxPajantImageCtrl();
this.OutputFileButton = new System.Windows.Forms.Button();
this.OutputImageWidthCtrl = new System.Windows.Forms.NumericUpDown();
this.InputFileButton = new System.Windows.Forms.Button();
this.OutputImageHeightCtrl = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.DismissButton = new System.Windows.Forms.Button();
this.RunButton = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.NumberOfGoresCtrl = new System.Windows.Forms.NumericUpDown();
this.OverlapGoresByCtrl = new System.Windows.Forms.NumericUpDown();
this.label8 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.axPajantImageCtrl1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.OutputImageWidthCtrl)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.OutputImageHeightCtrl)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NumberOfGoresCtrl)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.OverlapGoresByCtrl)).BeginInit();
this.SuspendLayout();
//
// axPajantImageCtrl1
//
this.axPajantImageCtrl1.Enabled = true;
this.axPajantImageCtrl1.Location = new System.Drawing.Point(440, 8);
this.axPajantImageCtrl1.Name = "axPajantImageCtrl1";
this.axPajantImageCtrl1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axPajantImageCtrl1.OcxState")));
this.axPajantImageCtrl1.Size = new System.Drawing.Size(288, 192);
this.axPajantImageCtrl1.TabIndex = 0;
//
// OutputFileButton
//
this.OutputFileButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.OutputFileButton.Location = new System.Drawing.Point(88, 144);
this.OutputFileButton.Name = "OutputFileButton";
this.OutputFileButton.Size = new System.Drawing.Size(344, 48);
this.OutputFileButton.TabIndex = 1;
this.OutputFileButton.Text = "out.jpg";
this.OutputFileButton.Click += new System.EventHandler(this.OutputFileButton_Click);
//
// OutputImageWidthCtrl
//
this.OutputImageWidthCtrl.Location = new System.Drawing.Point(88, 200);
this.OutputImageWidthCtrl.Maximum = new System.Decimal(new int[] {
8192,
0,
0,
0});
this.OutputImageWidthCtrl.Minimum = new System.Decimal(new int[] {
512,
0,
0,
0});
this.OutputImageWidthCtrl.Name = "OutputImageWidthCtrl";
this.OutputImageWidthCtrl.TabIndex = 2;
this.OutputImageWidthCtrl.Value = new System.Decimal(new int[] {
512,
0,
0,
0});
//
// InputFileButton
//
this.InputFileButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.InputFileButton.Location = new System.Drawing.Point(88, 48);
this.InputFileButton.Name = "InputFileButton";
this.InputFileButton.Size = new System.Drawing.Size(344, 48);
this.InputFileButton.TabIndex = 3;
this.InputFileButton.Text = "in.jpg";
this.InputFileButton.Click += new System.EventHandler(this.InputFileButton_Click);
//
// OutputImageHeightCtrl
//
this.OutputImageHeightCtrl.Location = new System.Drawing.Point(88, 240);
this.OutputImageHeightCtrl.Maximum = new System.Decimal(new int[] {
4096,
0,
0,
0});
this.OutputImageHeightCtrl.Minimum = new System.Decimal(new int[] {
256,
0,
0,
0});
this.OutputImageHeightCtrl.Name = "OutputImageHeightCtrl";
this.OutputImageHeightCtrl.TabIndex = 4;
this.OutputImageHeightCtrl.Value = new System.Decimal(new int[] {
256,
0,
0,
0});
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 104);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(160, 32);
this.label1.TabIndex = 5;
this.label1.Text = "Output Image";
//
// label2
//
this.label2.Location = new System.Drawing.Point(24, 144);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(56, 24);
this.label2.TabIndex = 6;
this.label2.Text = "Name:";
//
// label3
//
this.label3.Location = new System.Drawing.Point(24, 200);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 32);
this.label3.TabIndex = 7;
this.label3.Text = "Width";
//
// label4
//
this.label4.Location = new System.Drawing.Point(24, 240);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(56, 32);
this.label4.TabIndex = 8;
this.label4.Text = "Height";
//
// label5
//
this.label5.Location = new System.Drawing.Point(8, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(160, 32);
this.label5.TabIndex = 9;
this.label5.Text = "Input Image";
//
// label6
//
this.label6.Location = new System.Drawing.Point(24, 48);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(56, 24);
this.label6.TabIndex = 10;
this.label6.Text = "Name:";
//
// DismissButton
//
this.DismissButton.Location = new System.Drawing.Point(544, 320);
this.DismissButton.Name = "DismissButton";
this.DismissButton.Size = new System.Drawing.Size(184, 32);
this.DismissButton.TabIndex = 11;
this.DismissButton.Text = "Dismiss";
this.DismissButton.Click += new System.EventHandler(this.DismissButton_Click);
//
// RunButton
//
this.RunButton.Location = new System.Drawing.Point(8, 320);
this.RunButton.Name = "RunButton";
this.RunButton.Size = new System.Drawing.Size(184, 32);
this.RunButton.TabIndex = 12;
this.RunButton.Text = "Run";
this.RunButton.Click += new System.EventHandler(this.RunButton_Click);
//
// label7
//
this.label7.Location = new System.Drawing.Point(24, 280);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(56, 32);
this.label7.TabIndex = 15;
this.label7.Text = "Gores";
//
// NumberOfGoresCtrl
//
this.NumberOfGoresCtrl.Location = new System.Drawing.Point(88, 280);
this.NumberOfGoresCtrl.Maximum = new System.Decimal(new int[] {
60,
0,
0,
0});
this.NumberOfGoresCtrl.Minimum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.NumberOfGoresCtrl.Name = "NumberOfGoresCtrl";
this.NumberOfGoresCtrl.TabIndex = 13;
this.NumberOfGoresCtrl.Value = new System.Decimal(new int[] {
1,
0,
0,
0});
//
// OverlapGoresByCtrl
//
this.OverlapGoresByCtrl.Location = new System.Drawing.Point(368, 280);
this.OverlapGoresByCtrl.Maximum = new System.Decimal(new int[] {
60,
0,
0,
0});
this.OverlapGoresByCtrl.Name = "OverlapGoresByCtrl";
this.OverlapGoresByCtrl.Size = new System.Drawing.Size(64, 20);
this.OverlapGoresByCtrl.TabIndex = 16;
this.OverlapGoresByCtrl.Value = new System.Decimal(new int[] {
1,
0,
0,
0});
//
// label8
//
this.label8.Location = new System.Drawing.Point(224, 280);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(144, 32);
this.label8.TabIndex = 17;
this.label8.Text = "Overap Gores by (degrees)";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(736, 358);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.label8,
this.OverlapGoresByCtrl,
this.label7,
this.NumberOfGoresCtrl,
this.RunButton,
this.DismissButton,
this.label6,
this.label5,
this.label4,
this.label3,
this.label2,
this.label1,
this.OutputImageHeightCtrl,
this.InputFileButton,
this.OutputImageWidthCtrl,
this.OutputFileButton,
this.axPajantImageCtrl1});
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.axPajantImageCtrl1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.OutputImageWidthCtrl)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.OutputImageHeightCtrl)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NumberOfGoresCtrl)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.OverlapGoresByCtrl)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void RunButton_Click(object sender, System.EventArgs e)
{
// In here is the object that does all the work.
PAJANTLib.PajantImage pi=axPajantImageCtrl1.pi;
// Tell the control that I am a registered user.
///string userName="You supply this to Pajant";
///string password="Pajant will provide this";
///pi.Register(userName, password);
string inputFileName= InputFileButton.Text;// string from text edit control
string outputFileName= OutputFileButton.Text; // string from text edit control
int N = (int) NumberOfGoresCtrl.Value; // number of gores from numeric spin edit control
int Wo= (int) OutputImageWidthCtrl.Value; // output image width from numeric spin edit control
int Ho= (int)OutputImageHeightCtrl.Value; // output image height from numeric spin edit control
double slack = (double) OverlapGoresByCtrl.Value; // amount of slack in the map-to-gore projection calculation
// Load the JPG file into the control.
pi.Load(inputFileName, 0);
int Wi=pi.Width; // width of input image
int Hi=pi.Height; // height of input image
byte [,] r=new byte[Wo,Ho]; // red values of each position in the output image
byte [,] g=new byte[Wo,Ho]; // green values of each position in the output image
byte [,] b=new byte[Wo,Ho]; // blue values of each position in the output image
double W = 360.0/N; // the width of a gore.
for(int yo=0; yo<Ho; yo++)
{
double yg=180.0*yo/Ho-90.0; // the latitude on the globe, which corresponds to the y-coordinate yo on the output image.
double cosyg=Math.Cos(yg*Math.PI/180.0);
for(int xo=0; xo<Wo;xo++)
{
double xgs=360.0*xo/Wo-180.0; // the x coordinate (in degrees)of the location on the sinusoidally projected map, which corresponds to
// the x-coordinate xo on the output image.
int i= (int) Math.Round(Math.Floor(1.0+(xgs+180.0)/W)); // the gore number in which xgs and xgr lie (leftmost gore = number 1; rightmost = number N)
double c=(i-0.5)*W-180.0; // longitude of the centre of gore #i
double xgr=(xgs-c)/cosyg+c; // the x coordinate (in degrees) (i.e. the longitude) of the location on the globe which corresponds to
// the x coordinate xo on the output image.
if(xgr-slack/2>i*W-180.0 || xgr+slack/2<(i-1.0)*W-180.0) // (xo,yo) is a point that lies between the gores on the projection onto the output image, so colour it grey
// (note allow a bit of slack!)
{
r[xo,yo]=127;
g[xo,yo]=127;
b[xo,yo]=127;
}
else
{
// find the point (xi,yi) on the input image that corresponds to (xgs,yg) on the sinusoidally projected map.
double xi=Wi*(xgr+180)/360.0;
double yi=Hi*(yg+90.0)/180.0;
if(xi>=Wi || yi>=Hi || xi<0 || yi <0 ) // (xo, yo) corresponds to a point entirely outside the input image,
// so colour it grey
{
r[xo,yo]=127;
g[xo,yo]=127;
b[xo,yo]=127;
}
else
{
// interpolate a value of r g and b for (xo,yo) in the output image based upon the values at the grid-points surrounding
// (xi,yi) in the input image
int xb= (int) Math.Round(Math.Floor(xi)); // the integer x coordinate before xi
int xa=xb+1;
int yb= (int) Math.Round(Math.Floor(yi)); // the integer y coordinate before yi
int ya=yb+1;
/*
byte Rbb=0, Gbb=0, Bbb=0;
GetPixel(xb,yb, ref Rbb, ref Gbb, ref Bbb);
r[xo,yo]=Rbb;
g[xo,yo]=Gbb;
b[xo,yo]=Bbb;
*/
if(ya==Hi && xa==Wi) // (xb,yb) is the top right right point of the image - don't interpolate at all
{
byte Rbb=0, Gbb=0, Bbb=0;
GetPixel(xb,yb, ref Rbb, ref Gbb, ref Bbb);
r[xo,yo]=Rbb;
g[xo,yo]=Gbb;
b[xo,yo]=Bbb;
}
else if(ya==Hi) // and xa!=Wi: (xb,yb) lies in the top line of the image - linear interpolate horizontally
{
byte Rbb=0, Gbb=0, Bbb=0, Rab=0, Gab=0, Bab=0;
GetPixel(xb,yb, ref Rbb, ref Gbb, ref Bbb);
GetPixel(xa,yb, ref Rab, ref Gab, ref Bab);
r[xo,yo]= (byte) Math.Round(Lerp1(Rbb,Rab,xi-xb));
g[xo,yo]= (byte) Math.Round(Lerp1(Gbb,Gab,xi-xb));
b[xo,yo]= (byte) Math.Round(Lerp1(Bbb,Bab,xi-xb));
}
else if(xa==Wi) // and ya!=Hi: (xb,yb) lies in the rightmost line of the image - linear interpolate vertically
{
byte Rbb=0, Gbb=0, Bbb=0, Rba=0, Gba=0, Bba=0;
GetPixel(xb,yb, ref Rbb, ref Gbb, ref Bbb);
GetPixel(xb,ya, ref Rba, ref Gba, ref Bba);
r[xo,yo]= (byte) Math.Round(Lerp1(Rbb,Rba,yi-yb));
g[xo,yo]= (byte) Math.Round(Lerp1(Gbb,Gba,yi-yb));
b[xo,yo]= (byte) Math.Round(Lerp1(Bbb,Bba,yi-yb));
}
else // do a bilinear interpolation
{
byte Rbb=0, Gbb=0, Bbb=0, Rab=0, Gab=0, Bab=0, Rba=0, Gba=0, Bba=0, Raa=0, Gaa=0, Baa=0;
GetPixel(xb,yb, ref Rbb, ref Gbb, ref Bbb);
GetPixel(xa,yb, ref Rab, ref Gab, ref Bab);
GetPixel(xb,ya, ref Rba, ref Gba, ref Bba);
GetPixel(xa,ya, ref Raa, ref Gaa, ref Baa);
r[xo,yo]= (byte) Math.Round(BLerp1(Rbb,Rab,Rba,Raa,
xi-xb, yi-yb));
g[xo,yo]= (byte) Math.Round(BLerp1(Gbb,Gab,Gba,Gaa,
xi-xb, yi-yb));
b[xo,yo]= (byte) Math.Round(BLerp1(Bbb,Bab,Bba,Baa,
xi-xb, yi-yb));
}
}
}
}
}
// The arrays r[,], g[,] and b[,] now contain the RGB values that we want to write in the output image.
// prepare the control to hold our output image.
pi.ResizeImage(Wo,Ho,PJT_NEWIMAGE);
// Write the RGB values into the control
for(int yo=0; yo<Ho; yo++)
{
for(int xo=0; xo<Wo;xo++)
{
SetPixel(xo,yo,r[xo,yo],g[xo,yo],b[xo,yo]);
}
}
// save the output image into the file
pi.Save(outputFileName, 0);
} // end of method RunButton_Click
private void GetPixel(int x, int y, ref byte r, ref byte g, ref byte b)
{
PAJANTLib.PajantImage pi=axPajantImageCtrl1.pi;
int rgb=0, dummy=0;
pi.GetPixel(x,y, ref rgb, ref dummy, ref dummy, ref dummy, PJT_COORDINATES | PJT_COLORREF);
int ri=(rgb & 0x00FF0000) >> 16;
int gi=(rgb & 0x0000FF00) >> 8;
int bi=rgb & 0x000000FF;
r= (byte) ri;
g= (byte) gi;
b= (byte) bi;
}
private void SetPixel(int x, int y, byte r, byte g, byte b)
{
PAJANTLib.PajantImage pi=axPajantImageCtrl1.pi;
int dummy=0;
int ri=r; ri<<=16;
int gi=g; gi<<=8;
int bi=b;
pi.SetPixel(x,y, ri|gi|bi, dummy, dummy, dummy, PJT_COORDINATES | PJT_COLORREF);
}
private double Lerp1(double vb, double va, double x) // linear interpolation between vb and va, assuming that the grid points are 1 unit apart and x is between 0 and 1.
{
double v=vb+x*(va-vb);
return v;
}
private double BLerp1(double vbb, double vab, double vba, double vaa, double x, double y) // bilinear interpolation between vbb, vba, vab and vaa, assuming that the grid points are 1 unit apart and x and y are between 0 and 1.
{
double v=(1-x)*(1-y)*vbb + x*(1-y)*vab + x*y*vaa + (1-x)*y*vba;
return v;
}
private int PJT_COLORREF=0x100;
private int PJT_COORDINATES=0x1;
private int PJT_NEWIMAGE=0x3;
private void InputFileButton_Click(object sender, System.EventArgs e)
{
Stream myStream;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\" ;
openFileDialog1.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;
openFileDialog1.FilterIndex = 2 ;
openFileDialog1.RestoreDirectory = true ;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
if((myStream = openFileDialog1.OpenFile())!= null)
{
myStream.Close();
InputFileButton.Text=openFileDialog1.FileName;
}
else
{
MessageBox.Show("Cannot open file: "+openFileDialog1.FileName);
}
}
}
private void OutputFileButton_Click(object sender, System.EventArgs e)
{
Stream myStream ;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;
saveFileDialog1.FilterIndex = 2 ;
saveFileDialog1.RestoreDirectory = true ;
if(saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if((myStream = saveFileDialog1.OpenFile()) != null)
{
myStream.Close();
OutputFileButton.Text=saveFileDialog1.FileName;
}
else
{
MessageBox.Show("Cannot write file: "+saveFileDialog1.FileName);
}
}
}
private void DismissButton_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
};
}