3 using System.Drawing.Imaging;
4 using System.Runtime.Serialization;
7 using imageio = javax.imageio;
8 using stream = javax.imageio.stream;
9 using spi = javax.imageio.spi;
10 using BufferedImage = java.awt.image.BufferedImage;
11 using JavaImage = java.awt.Image;
13 using image = java.awt.image;
15 namespace System.Drawing
17 public sealed class Bitmap : Image {
21 Bitmap (Bitmap orig):base (orig) {}
23 private Bitmap (SerializationInfo info, StreamingContext context) {
24 throw new NotImplementedException ();
27 public Bitmap (int width, int height, Graphics g) {
28 throw new NotImplementedException();
31 public Bitmap (Image orig, Size newSize)
32 :this (orig, newSize.Width, newSize.Height) {}
34 public Bitmap (Image orig, int width, int height)
35 :base (CreateScaledImage (orig, width, height), ImageFormat.Bmp) {}
37 public Bitmap (int width, int height)
38 :this (width, height, PixelFormat.Format32bppArgb) {}
40 public Bitmap (Image original)
41 :this (original, original.Size) {}
43 public Bitmap (Stream stream)
44 :this (stream, false) {}
46 public Bitmap (string filename)
47 :this (filename, false) {}
49 internal Bitmap (java.awt.Image nativeObject, ImageFormat format)
50 :base (nativeObject, format) {}
52 private Bitmap (java.awt.Image nativeObject, ImageFormat format, PixelFormat pixFormat)
53 :this (nativeObject, format) {
54 if (pixFormat != this.PixelFormat)
55 throw new NotImplementedException ("Converting PixelFormat is not implemented yet.");
58 public Bitmap (int width, int height, PixelFormat format)
60 new java.awt.image.BufferedImage (width, height,
61 ToBufferedImageFormat (format)),
64 //TBD: why the following 3 lines are necessary?
65 // java.awt.Graphics2D graphics2d = NativeObject.createGraphics();
66 // graphics2d.drawImage(NativeObject, 0, 0, null);
67 // graphics2d.dispose();
70 public Bitmap (Stream stream, bool useIcm)
71 :this (stream, useIcm, null) {}
73 public Bitmap (string filename, bool useIcm)
74 :this (filename, useIcm, null) {}
76 internal Bitmap (Stream stream, bool useIcm, ImageFormat format) {
78 //FIXME: use direct ImageInputStream wrapper for NET Stream
79 io.InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
80 Initialize (new stream.MemoryCacheImageInputStream (jis), format);
83 internal Bitmap (string filename, bool useIcm, ImageFormat format) {
85 java.io.File file = vmw.common.IOUtils.getJavaFile (filename);
87 //TBD: check what exception throws NET
88 throw new System.IO.IOException ("File not found: "+filename);
89 Initialize (new stream.FileImageInputStream (file), format);
92 public Bitmap (Type type, string resource) {
93 using (Stream s = type.Assembly.GetManifestResourceStream (resource)) {
95 //TBD: check what type is thrown in MS
96 throw new Exception("Resource name was not found: `" + resource + "'");
97 io.InputStream jis = vmw.common.IOUtils.ToInputStream (s);
99 Initialize (new stream.MemoryCacheImageInputStream (jis), null);
101 catch (Exception e) {
102 //FIXME: catch and throw right exception
103 throw new Exception ("java exception", e);
108 //FIXME: should go to imageio helpers class
109 static ImageFormat MimeTypesToImageFormat (string [] mimeTypes)
111 foreach (ImageCodecInfo codec in ImageCodecInfo.Decoders.Values)
112 for (int i=0; i<mimeTypes.Length; i++)
113 if (codec.MimeType == mimeTypes [i])
114 return new ImageFormat (codec.FormatID);
118 private void Initialize (stream.ImageInputStream input, ImageFormat format) {
119 java.util.Iterator iter = null;
121 iter = imageio.ImageIO.getImageReadersByMIMEType (
122 ImageCodecInfo.ImageFormatToMimeType (format));
124 iter = imageio.ImageIO.getImageReaders (input);
126 if (!iter.hasNext ())
127 throw new ArgumentException ("Format not found"); //TBD: make same text as MS
129 imageio.ImageReader r = (imageio.ImageReader) iter.next ();
134 format = MimeTypesToImageFormat (r.getOriginatingProvider ().getMIMETypes ());
136 Initialize (r, format);
139 private void Initialize (imageio.ImageReader r, ImageFormat format) {
140 java.awt.Image [] nativeObjects;
141 java.awt.Image [] thumbnails = null;
143 nativeObjects = new BufferedImage [r.getNumImages (false)];
144 for (int i = 0; i < nativeObjects.Length; i++) {
145 if (r.hasThumbnails(i)) {
146 if (thumbnails == null)
147 thumbnails = new BufferedImage[nativeObjects.Length];
149 thumbnails[i] = r.readThumbnail(i, 0);
151 nativeObjects [i] = r.read (i);
155 catch (Exception e) {
156 //TDB: make exception same as in MS
157 throw new ArgumentException ("Error reading", e);
159 base.Initialize (nativeObjects, thumbnails, format, FrameDimension.Page.Guid);
163 public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
165 throw new NotImplementedException();
171 protected override void InternalSave (stream.ImageOutputStream output, Guid clsid) {
172 string mime=ImageCodecInfo.FindEncoder (clsid).MimeType;
173 imageio.ImageWriter writer = null;;
175 writer = (imageio.ImageWriter) imageio.ImageIO.getImageWritersByMIMEType (mime).next ();
176 writer.setOutput (output);
177 if (NativeObjectsCount == 1)
178 writer.write (NativeObject);
179 else if (writer.canWriteSequence ())
180 SaveSequence (writer);
182 throw new NotImplementedException ();
184 catch (Exception e) {
185 //FIXME: check dotnet exceptions in save, and throw same types
186 throw new Exception ("java threw an exception", e);
190 void SaveSequence (imageio.ImageWriter writer) {
191 //FIXME: does not supports metadata and thumbnails for now
192 writer.prepareWriteSequence (null);
194 for (int i = 0; i < NativeObjectsCount; i++) {
195 imageio.IIOImage iio = new imageio.IIOImage ((BufferedImage)this[i], null, null);
196 writer.writeToSequence (iio, null);
199 writer.endWriteSequence ();
204 #region private statics: ToBufferedImageFormat, CreateScaledImage
206 private static int ToBufferedImageFormat (PixelFormat format) {
208 case PixelFormat.Format16bppGrayScale:
209 return BufferedImage.TYPE_USHORT_GRAY;
210 case PixelFormat.Format1bppIndexed:
211 return BufferedImage.TYPE_BYTE_GRAY;
212 case PixelFormat.Format32bppArgb:
213 return BufferedImage.TYPE_INT_ARGB;
214 case PixelFormat.Format32bppRgb:
215 return BufferedImage.TYPE_INT_RGB;
216 case PixelFormat.Format32bppPArgb:
217 return BufferedImage.TYPE_INT_ARGB_PRE;
218 case PixelFormat.Format16bppRgb555:
219 return BufferedImage.TYPE_USHORT_555_RGB;
220 case PixelFormat.Format16bppRgb565:
221 return BufferedImage.TYPE_USHORT_565_RGB;
222 case PixelFormat.Indexed:
223 return BufferedImage.TYPE_BYTE_INDEXED;
229 private static java.awt.Image CreateScaledImage(Image original, int width, int height) {
230 JavaImage oldscaled = original.NativeObject.getScaledInstance(width, height,
231 JavaImage.SCALE_DEFAULT);
232 BufferedImage newimage = new BufferedImage(oldscaled.getWidth(null),
233 oldscaled.getHeight(null),
234 BufferedImage.TYPE_INT_ARGB);
235 java.awt.Graphics2D graphics2d = newimage.createGraphics();
236 graphics2d.drawImage(oldscaled, 0, 0, null);
237 graphics2d.dispose();
243 public Color GetPixel (int x, int y)
246 int argb = NativeObject.getRGB(x,y);
247 return Color.FromArgb(argb);
250 public void SetPixel (int x, int y, Color color)
252 int rgb = color.ToArgb();
253 NativeObject.setRGB(x,y,rgb);
258 public override object Clone () {
259 return new Bitmap (this);
262 public Bitmap Clone (Rectangle rect, PixelFormat format)
264 BufferedImage sub = NativeObject.getSubimage(rect.X,rect.Y,rect.Width,rect.Height);
265 return new Bitmap(sub, RawFormat, format);
268 public Bitmap Clone (RectangleF rect, PixelFormat format)
270 //TODO: check if there is more precise API
271 BufferedImage sub = NativeObject.getSubimage((int)rect.X,(int)rect.Y,(int)rect.Width,(int)rect.Height);
272 return new Bitmap(sub, RawFormat, format);
276 #region LockBits [TODO]
277 public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) {
278 throw new NotImplementedException();
282 #region MakeTransparent
283 public void MakeTransparent ()
285 Color clr = GetPixel(0,0);
286 MakeTransparent (clr);
289 public void MakeTransparent (Color transparentColor)
291 byte A = transparentColor.A;
292 image.WritableRaster raster = NativeObject.getRaster();
293 int numBands = raster.getNumBands();
294 int maxWidth = raster.getWidth() + raster.getMinX();
295 int maxHeight = raster.getHeight() + raster.getMinY();
296 int[] srcPix = new int[numBands];
298 for (int y = raster.getMinY(); y < maxHeight; y++) {
299 for (int x = raster.getMinX(); x < maxWidth; x++) {
300 /*srcPix =*/ raster.getPixel(x, y, srcPix);
301 for (int z = 0; z < numBands; z++) {
302 int argb = srcPix[z];
303 if ((uint)argb >> 24 == A) {
313 #region SetResolution [TODO]
314 public void SetResolution (float xDpi, float yDpi)
316 throw new NotImplementedException();
320 #region UnlockBits [TODO]
321 public void UnlockBits (BitmapData bitmap_data)
323 throw new NotImplementedException();
328 internal new BufferedImage NativeObject {
330 return (BufferedImage)base.NativeObject;
334 protected override java.awt.Image[] CloneNativeObjects(java.awt.Image[] src) {
338 awt.Image[] dst = new awt.Image[src.Length];
339 for (int i = 0; i < dst.Length; i++) {
340 BufferedImage image = src[i] as BufferedImage;
342 throw new ArgumentException(String.Format("Unsupported image type '{0}'", src[i].ToString()), "src");
344 dst[i] = new BufferedImage(image.getColorModel(), image.copyData(null), image.isAlphaPremultiplied(), null);
352 #region InternalPixelFormat
353 protected override PixelFormat InternalPixelFormat {
355 int t = NativeObject.getType();
357 case 11://JavaImage.TYPE_USHORT_GRAY:
358 return PixelFormat.Format16bppGrayScale;
359 case 10://JavaImage.TYPE_BYTE_GRAY:
360 return PixelFormat.Format1bppIndexed;
361 case 1: //JavaImage.TYPE_INT_RGB
362 return PixelFormat.Format32bppRgb;
363 case 2: //JavaImage.TYPE_INT_ARGB:
364 return PixelFormat.Format32bppArgb;
365 case 3://JavaImage.TYPE_INT_ARGB_PRE:
366 return PixelFormat.Format32bppPArgb;
367 case 9://JavaImage.TYPE_USHORT_555_RGB:
368 return PixelFormat.Format16bppRgb555;
369 case 8://JavaImage.TYPE_USHORT_565_RGB:
370 return PixelFormat.Format16bppRgb565;
371 case 13://JavaImage.TYPE_BYTE_INDEXED:
372 return PixelFormat.Indexed;
374 case 12://JavaImage.TYPE_BYTE_BINARY:
375 case 0://JavaImage.TYPE_CUSTOM:
376 case 4://JavaImage.TYPE_INT_BGR:
377 case 5://JavaImage.TYPE_3BYTE_BGR:
378 case 6://JavaImage.TYPE_4BYTE_ABGR:
379 case 7://JavaImage.TYPE_4BYTE_ABGR_PRE:
381 return PixelFormat.Undefined;
388 public static Bitmap FromHicon (IntPtr hicon)
390 throw new NotImplementedException();
393 public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested
395 throw new NotImplementedException();
398 public IntPtr GetHbitmap ()
400 throw new NotImplementedException();
403 public IntPtr GetHbitmap (Color background)
405 throw new NotImplementedException();
408 public IntPtr GetHicon ()
410 throw new NotImplementedException();