OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
GenericSystemDrawing.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Drawing;
30 using System.Drawing.Imaging;
31 using System.IO;
32 using OpenSim.Region.Framework.Interfaces;
33 using OpenSim.Region.Framework.Scenes;
34 
35 namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
36 {
44  {
45  #region ITerrainLoader Members
46 
47  public string FileExtension
48  {
49  get { return ".gsd"; }
50  }
51 
60  public virtual ITerrainChannel LoadFile(string filename)
61  {
62  using (Bitmap b = new Bitmap(filename))
63  return LoadBitmap(b);
64  }
65 
66  public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h)
67  {
68  using (Bitmap bitmap = new Bitmap(filename))
69  {
70  ITerrainChannel retval = new TerrainChannel(w, h);
71 
72  for (int x = 0; x < retval.Width; x++)
73  {
74  for (int y = 0; y < retval.Height; y++)
75  {
76  retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128;
77  }
78  }
79 
80  return retval;
81  }
82  }
83 
84  public virtual ITerrainChannel LoadStream(Stream stream)
85  {
86  using (Bitmap b = new Bitmap(stream))
87  return LoadBitmap(b);
88  }
89 
90  protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap)
91  {
92  ITerrainChannel retval = new TerrainChannel(bitmap.Width, bitmap.Height);
93 
94  int x;
95  for (x = 0; x < bitmap.Width; x++)
96  {
97  int y;
98  for (y = 0; y < bitmap.Height; y++)
99  {
100  retval[x, y] = bitmap.GetPixel(x, bitmap.Height - y - 1).GetBrightness() * 128;
101  }
102  }
103 
104  return retval;
105  }
106 
112  public virtual void SaveFile(string filename, ITerrainChannel map)
113  {
114  Bitmap colours = CreateGrayscaleBitmapFromMap(map);
115 
116  colours.Save(filename, ImageFormat.Png);
117  }
118 
124  public virtual void SaveStream(Stream stream, ITerrainChannel map)
125  {
126  Bitmap colours = CreateGrayscaleBitmapFromMap(map);
127 
128  colours.Save(stream, ImageFormat.Png);
129  }
130 
131  public virtual void SaveFile(ITerrainChannel m_channel, string filename,
132  int offsetX, int offsetY,
133  int fileWidth, int fileHeight,
134  int regionSizeX, int regionSizeY)
135 
136  {
137  // We need to do this because:
138  // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
139  string tempName = Path.GetTempFileName();
140 
141  Bitmap existingBitmap = null;
142  Bitmap thisBitmap = null;
143  Bitmap newBitmap = null;
144 
145  try
146  {
147  if (File.Exists(filename))
148  {
149  File.Copy(filename, tempName, true);
150  existingBitmap = new Bitmap(tempName);
151  if (existingBitmap.Width != fileWidth * regionSizeX || existingBitmap.Height != fileHeight * regionSizeY)
152  {
153  // old file, let's overwrite it
154  newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
155  }
156  else
157  {
158  newBitmap = existingBitmap;
159  }
160  }
161  else
162  {
163  newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
164  }
165 
166  thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
167  // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
168  for (int x = 0; x < regionSizeX; x++)
169  for (int y = 0; y < regionSizeY; y++)
170  newBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
171 
172  Save(newBitmap, filename);
173  }
174  finally
175  {
176  if (existingBitmap != null)
177  existingBitmap.Dispose();
178 
179  if (thisBitmap != null)
180  thisBitmap.Dispose();
181 
182  if (newBitmap != null)
183  newBitmap.Dispose();
184 
185  if (File.Exists(tempName))
186  File.Delete(tempName);
187  }
188  }
189 
190  protected virtual void Save(Bitmap bmp, string filename)
191  {
192  bmp.Save(filename, ImageFormat.Png);
193  }
194 
195  #endregion
196 
197  public override string ToString()
198  {
199  return "SYS.DRAWING";
200  }
201 
202  //Returns true if this extension is supported for terrain save-tile
203  public virtual bool SupportsTileSave()
204  {
205  return false;
206  }
207 
214  protected static Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
215  {
216  // Bitmap bmp = new Bitmap(map.Width, map.Height, PixelFormat.Format24bppRgb);
217  Bitmap bmp = new Bitmap(map.Width, map.Height);
218 
219 
220  const int pallete = 256;
221 
222  Color[] grays = new Color[pallete];
223  for (int i = 0; i < grays.Length; i++)
224  {
225  grays[i] = Color.FromArgb(i, i, i);
226  }
227 
228  for (int y = 0; y < map.Height; y++)
229  {
230  for (int x = 0; x < map.Width; x++)
231  {
232  // to change this, loading also needs change
233 
234  // int colorindex = (int)map[x, y]; // one to one conversion 0 - 255m range
235  // int colorindex = (int)map[x, y] / 2; // 0 - 510 range
236 
237  int colorindex = (int)map[x, y] * 2; // the original 0 - 127.5 range
238 
239  // clamp it not adding the red warning
240  if (colorindex < 0)
241  colorindex = 0;
242  else if (colorindex >= pallete)
243  colorindex = pallete - 1;
244  bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
245  }
246  }
247  return bmp;
248  }
249  }
250 }
251 
252 
virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h)
virtual void SaveFile(ITerrainChannel m_channel, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY)
Save a number of map tiles to a single big image file.
virtual void SaveStream(Stream stream, ITerrainChannel map)
Exports a stream using a System.Drawing exporter.
static Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
Protected method, generates a grayscale bitmap image from a specified terrain channel.
A new version of the old Channel class, simplified
A virtual class designed to have methods overloaded, this class provides an interface for a generic i...
virtual void SaveFile(string filename, ITerrainChannel map)
Exports a file to a image on the disk using a System.Drawing exporter.
virtual ITerrainChannel LoadFile(string filename)
Loads a file from a specified filename on the disk, parses the image using the System.Drawing parsers then returns a terrain channel. Values are returned based on HSL brightness between 0m and 128m