Bitmap.jvm.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using System;
  2. using System.IO;
  3. using System.Drawing.Imaging;
  4. using System.Runtime.Serialization;
  5. using java.io;
  6. using javax.imageio;
  7. using javax.imageio.stream;
  8. using javax.imageio.spi;
  9. using BufferedImage = java.awt.image.BufferedImage;
  10. using JavaImage = java.awt.Image;
  11. using awt = java.awt;
  12. using image = java.awt.image;
  13. namespace System.Drawing
  14. {
  15. public sealed class Bitmap : Image {
  16. #region constructors
  17. Bitmap (Bitmap orig):base (orig) {}
  18. private Bitmap (SerializationInfo info, StreamingContext context) {
  19. throw new NotImplementedException ();
  20. }
  21. public Bitmap (int width, int height, Graphics g) {
  22. throw new NotImplementedException();
  23. }
  24. public Bitmap (Image orig, Size newSize)
  25. :this (orig, newSize.Width, newSize.Height) {}
  26. public Bitmap (Image orig, int width, int height)
  27. :base (CreateScaledImage (orig, width, height), ImageFormat.Bmp) {}
  28. public Bitmap (int width, int height)
  29. :this (width, height, PixelFormat.Format32bppArgb) {}
  30. public Bitmap (Image original)
  31. :this (original, original.Size) {}
  32. public Bitmap (Stream stream)
  33. :this (stream, false) {}
  34. public Bitmap (string filename)
  35. :this (filename, false) {}
  36. internal Bitmap (java.awt.Image nativeObject, ImageFormat format)
  37. :base (nativeObject, format) {}
  38. private Bitmap (java.awt.Image nativeObject, ImageFormat format, PixelFormat pixFormat)
  39. :this (nativeObject, format) {
  40. if (pixFormat != this.PixelFormat)
  41. throw new NotImplementedException ("Converting PixelFormat is not implemented yet.");
  42. }
  43. public Bitmap (int width, int height, PixelFormat format)
  44. :base (
  45. new java.awt.image.BufferedImage (width, height,
  46. ToBufferedImageFormat (format)),
  47. ImageFormat.Bmp)
  48. {
  49. //TBD: why the following 3 lines are necessary?
  50. // java.awt.Graphics2D graphics2d = NativeObject.createGraphics();
  51. // graphics2d.drawImage(NativeObject, 0, 0, null);
  52. // graphics2d.dispose();
  53. }
  54. public Bitmap (Stream stream, bool useIcm)
  55. :this (stream, null) {}
  56. public Bitmap (string filename, bool useIcm)
  57. //FIXME: useIcm param
  58. :this (filename, null) {}
  59. internal Bitmap (Stream stream, ImageFormat format) {
  60. //FIXME: useIcm param
  61. //FIXME: use direct ImageInputStream wrapper for NET Stream
  62. InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
  63. Initialize (new MemoryCacheImageInputStream (jis), format);
  64. }
  65. internal Bitmap (string filename, ImageFormat format) {
  66. java.io.File file = vmw.common.IOUtils.getJavaFile (filename);
  67. if (!file.exists ())
  68. //TBD: check what exception throws NET
  69. throw new System.IO.IOException ("File not found: "+filename);
  70. Initialize (new FileImageInputStream (file), format);
  71. }
  72. public Bitmap (Type type, string resource) {
  73. using (Stream s = type.Assembly.GetManifestResourceStream (resource)) {
  74. if (s == null)
  75. //TBD: check what type is thrown in MS
  76. throw new Exception("Resource name was not found: `" + resource + "'");
  77. InputStream jis = vmw.common.IOUtils.ToInputStream (s);
  78. Initialize (new MemoryCacheImageInputStream (jis), null);
  79. }
  80. }
  81. private void Initialize (ImageInputStream input, ImageFormat format) {
  82. if (format != null) {
  83. ImageReader r = format.ImageReaderSpi.createReaderInstance ();
  84. r.setInput (input);
  85. Initialize (r, format);
  86. }
  87. else {
  88. java.util.Iterator iter = ImageIO.getImageReaders (input);
  89. if (!iter.hasNext ())
  90. throw new ArgumentException ("Format not found"); //TBD: make same text as MS
  91. //following vars are initialized in the try block
  92. string mimeType;
  93. javax.imageio.spi.ImageReaderSpi readerSpi;
  94. ImageReader r;
  95. try {
  96. r = (ImageReader) iter.next ();
  97. r.setInput (input);
  98. readerSpi = r.getOriginatingProvider();
  99. mimeType = readerSpi.getMIMETypes() [0];
  100. }
  101. catch (Exception e) {
  102. //TBD: make same text as MS
  103. throw new ArgumentException ("Error reading", e);
  104. }
  105. format = new ImageFormat (mimeType, readerSpi, null);
  106. Initialize (r, format);
  107. }
  108. }
  109. private void Initialize (ImageReader r, ImageFormat format) {
  110. java.awt.Image [] nativeObjects;
  111. java.awt.Image [] thumbnails = null;
  112. try {
  113. nativeObjects = new BufferedImage [r.getNumImages (false)];
  114. for (int i = 0; i < nativeObjects.Length; i++) {
  115. if (r.hasThumbnails(i)) {
  116. if (thumbnails == null)
  117. thumbnails = new BufferedImage[nativeObjects.Length];
  118. thumbnails[i] = r.readThumbnail(i, 0);
  119. }
  120. nativeObjects [i] = r.read (i);
  121. }
  122. }
  123. catch (Exception e) {
  124. //TDB: make exception same as in MS
  125. throw new ArgumentException ("Error reading", e);
  126. }
  127. base.Initialize (nativeObjects, thumbnails, format, FrameDimension.Page.Guid);
  128. }
  129. #if INTPTR_SUPPORT
  130. public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
  131. {
  132. throw new NotImplementedException();
  133. }
  134. #endif
  135. #endregion
  136. #region InternalSave
  137. protected override void InternalSave (ImageOutputStream output, ImageFormat format) {
  138. ImageWriterSpi spi = format.ImageWriterSpi;
  139. if (spi == null)
  140. spi = ImageFormat.Png.ImageWriterSpi;
  141. ImageWriter writer = spi.createWriterInstance ();
  142. writer.setOutput (output);
  143. if (NativeObjectsCount == 1)
  144. writer.write (NativeObject);
  145. else if (writer.canWriteSequence ())
  146. SaveSequence ();
  147. else
  148. throw new NotImplementedException ();
  149. }
  150. void SaveSequence () {
  151. //FIXME: does not supports metadata and thumbnails for now
  152. ImageWriter writer = RawFormat.ImageWriterSpi.createWriterInstance ();
  153. writer.prepareWriteSequence (null);
  154. for (int i = 0; i < NativeObjectsCount; i++) {
  155. IIOImage iio = new IIOImage ((BufferedImage)this[i], null, null);
  156. writer.writeToSequence (iio, null);
  157. }
  158. writer.endWriteSequence ();
  159. }
  160. #endregion
  161. #region private statics: ToBufferedImageFormat, CreateScaledImage
  162. private static int ToBufferedImageFormat (PixelFormat format) {
  163. switch(format) {
  164. case PixelFormat.Format16bppGrayScale:
  165. return BufferedImage.TYPE_USHORT_GRAY;
  166. case PixelFormat.Format1bppIndexed:
  167. return BufferedImage.TYPE_BYTE_GRAY;
  168. case PixelFormat.Format32bppArgb:
  169. return BufferedImage.TYPE_INT_ARGB;
  170. case PixelFormat.Format32bppRgb:
  171. return BufferedImage.TYPE_INT_RGB;
  172. case PixelFormat.Format32bppPArgb:
  173. return BufferedImage.TYPE_INT_ARGB_PRE;
  174. case PixelFormat.Format16bppRgb555:
  175. return BufferedImage.TYPE_USHORT_555_RGB;
  176. case PixelFormat.Format16bppRgb565:
  177. return BufferedImage.TYPE_USHORT_565_RGB;
  178. case PixelFormat.Indexed:
  179. return BufferedImage.TYPE_BYTE_INDEXED;
  180. default:
  181. return 0;
  182. }
  183. }
  184. private static java.awt.Image CreateScaledImage(Image original, int width, int height) {
  185. JavaImage oldscaled = original.NativeObject.getScaledInstance(width, height,
  186. JavaImage.SCALE_DEFAULT);
  187. BufferedImage newimage = new BufferedImage(oldscaled.getWidth(null),
  188. oldscaled.getHeight(null),
  189. BufferedImage.TYPE_INT_ARGB);
  190. java.awt.Graphics2D graphics2d = newimage.createGraphics();
  191. graphics2d.drawImage(oldscaled, 0, 0, null);
  192. graphics2d.dispose();
  193. return newimage;
  194. }
  195. #endregion
  196. #region Get-SetPixel
  197. public Color GetPixel (int x, int y)
  198. {
  199. int argb = NativeObject.getRGB(x,y);
  200. return Color.FromArgb(argb);
  201. }
  202. public void SetPixel (int x, int y, Color color)
  203. {
  204. int rgb = color.ToArgb();
  205. NativeObject.setRGB(x,y,rgb);
  206. }
  207. #endregion
  208. #region Clone
  209. public override object Clone () {
  210. return new Bitmap (this);
  211. }
  212. public Bitmap Clone (Rectangle rect, PixelFormat format)
  213. {
  214. BufferedImage sub = NativeObject.getSubimage(rect.X,rect.Y,rect.Width,rect.Height);
  215. return new Bitmap(sub, RawFormat, format);
  216. }
  217. public Bitmap Clone (RectangleF rect, PixelFormat format)
  218. {
  219. //TODO: check if there is more precise API
  220. BufferedImage sub = NativeObject.getSubimage((int)rect.X,(int)rect.Y,(int)rect.Width,(int)rect.Height);
  221. return new Bitmap(sub, RawFormat, format);
  222. }
  223. #endregion
  224. #region LockBits [TODO]
  225. public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) {
  226. throw new NotImplementedException();
  227. }
  228. #endregion
  229. #region MakeTransparent
  230. public void MakeTransparent ()
  231. {
  232. Color clr = GetPixel(0,0);
  233. MakeTransparent (clr);
  234. }
  235. public void MakeTransparent (Color transparentColor)
  236. {
  237. byte A = transparentColor.A;
  238. image.WritableRaster raster = NativeObject.getRaster();
  239. int numBands = raster.getNumBands();
  240. int maxWidth = raster.getWidth() + raster.getMinX();
  241. int maxHeight = raster.getHeight() + raster.getMinY();
  242. int[] srcPix = new int[numBands];
  243. for (int y = raster.getMinY(); y < maxHeight; y++) {
  244. for (int x = raster.getMinX(); x < maxWidth; x++) {
  245. /*srcPix =*/ raster.getPixel(x, y, srcPix);
  246. for (int z = 0; z < numBands; z++) {
  247. int argb = srcPix[z];
  248. if ((uint)argb >> 24 == A) {
  249. argb &= 0x00FFFFFF;
  250. srcPix[z] = argb;
  251. }
  252. }
  253. }
  254. }
  255. }
  256. #endregion
  257. #region SetResolution [TODO]
  258. public void SetResolution (float xDpi, float yDpi)
  259. {
  260. throw new NotImplementedException();
  261. }
  262. #endregion
  263. #region UnlockBits [TODO]
  264. public void UnlockBits (BitmapData bitmap_data)
  265. {
  266. throw new NotImplementedException();
  267. }
  268. #endregion
  269. #region NativeObject
  270. internal new BufferedImage NativeObject {
  271. get {
  272. return (BufferedImage)base.NativeObject;
  273. }
  274. }
  275. protected override java.awt.Image[] CloneNativeObjects(java.awt.Image[] src) {
  276. if (src == null)
  277. return null;
  278. awt.Image[] dst = new awt.Image[src.Length];
  279. for (int i = 0; i < dst.Length; i++) {
  280. BufferedImage image = src[i] as BufferedImage;
  281. if (image == null)
  282. throw new ArgumentException(String.Format("Unsupported image type '{0}'", src[i].ToString()), "src");
  283. dst[i] = new BufferedImage(image.getColorModel(), image.copyData(null), image.isAlphaPremultiplied(), null);
  284. }
  285. return dst;
  286. }
  287. #endregion
  288. #region InternalPixelFormat
  289. protected override PixelFormat InternalPixelFormat {
  290. get {
  291. int t = NativeObject.getType();
  292. switch(t) {
  293. case 11://JavaImage.TYPE_USHORT_GRAY:
  294. return PixelFormat.Format16bppGrayScale;
  295. case 10://JavaImage.TYPE_BYTE_GRAY:
  296. return PixelFormat.Format1bppIndexed;
  297. case 1: //JavaImage.TYPE_INT_RGB
  298. return PixelFormat.Format32bppRgb;
  299. case 2: //JavaImage.TYPE_INT_ARGB:
  300. return PixelFormat.Format32bppArgb;
  301. case 3://JavaImage.TYPE_INT_ARGB_PRE:
  302. return PixelFormat.Format32bppPArgb;
  303. case 9://JavaImage.TYPE_USHORT_555_RGB:
  304. return PixelFormat.Format16bppRgb555;
  305. case 8://JavaImage.TYPE_USHORT_565_RGB:
  306. return PixelFormat.Format16bppRgb565;
  307. case 13://JavaImage.TYPE_BYTE_INDEXED:
  308. return PixelFormat.Indexed;
  309. //TODO: support this
  310. case 12://JavaImage.TYPE_BYTE_BINARY:
  311. case 0://JavaImage.TYPE_CUSTOM:
  312. case 4://JavaImage.TYPE_INT_BGR:
  313. case 5://JavaImage.TYPE_3BYTE_BGR:
  314. case 6://JavaImage.TYPE_4BYTE_ABGR:
  315. case 7://JavaImage.TYPE_4BYTE_ABGR_PRE:
  316. default:
  317. return PixelFormat.Undefined;
  318. }
  319. }
  320. }
  321. #endregion
  322. #if INTPTR_SUPPORT
  323. public static Bitmap FromHicon (IntPtr hicon)
  324. {
  325. throw new NotImplementedException();
  326. }
  327. public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested
  328. {
  329. throw new NotImplementedException();
  330. }
  331. public IntPtr GetHbitmap ()
  332. {
  333. throw new NotImplementedException();
  334. }
  335. public IntPtr GetHbitmap (Color background)
  336. {
  337. throw new NotImplementedException();
  338. }
  339. public IntPtr GetHicon ()
  340. {
  341. throw new NotImplementedException();
  342. }
  343. #endif
  344. }
  345. }