using System.IO;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
+using Mainsoft.Drawing.Imaging;
using io = java.io;
using imageio = javax.imageio;
{
public sealed class Bitmap : Image {
+ # region Static fields
+
+ static readonly image.ColorModel _jpegColorModel = new image.DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
+
+ #endregion
+
#region constructors
- Bitmap (Bitmap orig):base (orig) {}
+ Bitmap (PlainImage orig) {
+ base.Initialize( orig, false );
+ }
+ [MonoTODO]
private Bitmap (SerializationInfo info, StreamingContext context) {
throw new NotImplementedException ();
}
- public Bitmap (int width, int height, Graphics g) {
- throw new NotImplementedException();
+ public Bitmap (int width, int height, Graphics g)
+ :this (width, height, PixelFormat.Format32bppArgb) {
+ CurrentImage.HorizontalResolution = g.DpiX;
+ CurrentImage.VerticalResolution = g.DpiY;
}
- public Bitmap (Image orig, Size newSize)
- :this (orig, newSize.Width, newSize.Height) {}
-
- public Bitmap (Image orig, int width, int height)
- :base (CreateScaledImage (orig, width, height), ImageFormat.Bmp) {}
-
- public Bitmap (int width, int height)
- :this (width, height, PixelFormat.Format32bppArgb) {}
-
public Bitmap (Image original)
:this (original, original.Size) {}
- public Bitmap (Stream stream)
- :this (stream, false) {}
+ public Bitmap (Image orig, Size newSize)
+ :this (orig, newSize.Width, newSize.Height) {}
- public Bitmap (string filename)
- :this (filename, false) {}
+ public Bitmap (Image orig, int width, int height)
+ :base (CreateScaledImage (orig, width, height), ImageFormat.MemoryBmp) {}
internal Bitmap (java.awt.Image nativeObject, ImageFormat format)
:base (nativeObject, format) {}
+ [MonoTODO]
private Bitmap (java.awt.Image nativeObject, ImageFormat format, PixelFormat pixFormat)
:this (nativeObject, format) {
if (pixFormat != this.PixelFormat)
throw new NotImplementedException ("Converting PixelFormat is not implemented yet.");
}
+ public Bitmap (int width, int height)
+ :this (width, height, PixelFormat.Format32bppArgb) {}
+
public Bitmap (int width, int height, PixelFormat format)
:base (
- new java.awt.image.BufferedImage (width, height,
- ToBufferedImageFormat (format)),
- ImageFormat.Bmp)
- {
- //TBD: why the following 3 lines are necessary?
-// java.awt.Graphics2D graphics2d = NativeObject.createGraphics();
-// graphics2d.drawImage(NativeObject, 0, 0, null);
-// graphics2d.dispose();
+ new java.awt.image.BufferedImage (width, height,
+ ToBufferedImageFormat (format)),
+ ImageFormat.Bmp) {
}
+ public Bitmap (Stream stream)
+ :this (stream, false) {}
+
+ public Bitmap (string filename)
+ :this (filename, false) {}
+
+ [MonoTODO]
public Bitmap (Stream stream, bool useIcm)
:this (stream, useIcm, null) {}
+ [MonoTODO]
public Bitmap (string filename, bool useIcm)
:this (filename, useIcm, null) {}
internal Bitmap (Stream stream, bool useIcm, ImageFormat format) {
- //FIXME: useIcm param
- //FIXME: use direct ImageInputStream wrapper for NET Stream
+ // TBD: useIcm param
io.InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
Initialize (new stream.MemoryCacheImageInputStream (jis), format);
}
internal Bitmap (string filename, bool useIcm, ImageFormat format) {
- //FIXME: useIcm param
- java.io.File file = vmw.common.IOUtils.getJavaFile (filename);
- if (!file.exists ())
- //TBD: check what exception throws NET
- throw new System.IO.IOException ("File not found: "+filename);
- Initialize (new stream.FileImageInputStream (file), format);
+ using(FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
+ // TBD: useIcm param
+ io.InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
+ Initialize (new stream.MemoryCacheImageInputStream (jis), format);
+ }
}
public Bitmap (Type type, string resource) {
using (Stream s = type.Assembly.GetManifestResourceStream (resource)) {
if (s == null)
- //TBD: check what type is thrown in MS
- throw new Exception("Resource name was not found: `" + resource + "'");
+ throw new ArgumentException("Resource '" + resource + "' could not be found in class '" + type.ToString() + "'");
+
io.InputStream jis = vmw.common.IOUtils.ToInputStream (s);
- try {
- Initialize (new stream.MemoryCacheImageInputStream (jis), null);
- }
- catch (Exception e) {
- //FIXME: catch and throw right exception
- throw new Exception ("java exception", e);
- }
+ Initialize (new stream.MemoryCacheImageInputStream (jis), null);
}
}
-
- //FIXME: should go to imageio helpers class
- static ImageFormat MimeTypesToImageFormat (string [] mimeTypes)
- {
- foreach (ImageCodecInfo codec in ImageCodecInfo.Decoders.Values)
- for (int i=0; i<mimeTypes.Length; i++)
- if (codec.MimeType == mimeTypes [i])
- return new ImageFormat (codec.FormatID);
- return null;
+#if INTPTR_SUPPORT
+ [MonoTODO]
+ public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
+ {
+ throw new NotImplementedException();
}
+#endif
+ #endregion
- private void Initialize (stream.ImageInputStream input, ImageFormat format) {
- java.util.Iterator iter = null;
- if (format != null)
- iter = imageio.ImageIO.getImageReadersByMIMEType (
- ImageCodecInfo.ImageFormatToMimeType (format));
- else
- iter = imageio.ImageIO.getImageReaders (input);
-
- if (!iter.hasNext ())
- throw new ArgumentException ("Format not found"); //TBD: make same text as MS
-
- imageio.ImageReader r = (imageio.ImageReader) iter.next ();
+ #region Internal Initialization
- r.setInput (input);
+ private void Initialize (stream.ImageInputStream input, ImageFormat format) {
+ ImageCodec ic = null;
if (format == null)
- format = MimeTypesToImageFormat (r.getOriginatingProvider ().getMIMETypes ());
+ ic = ImageCodec.CreateReader(input);
+ else
+ ic = ImageCodec.CreateReader(format);
- Initialize (r, format);
- }
+ if (ic == null)
+ throw new ArgumentException ("Parameter is not valid.");
- private void Initialize (imageio.ImageReader r, ImageFormat format) {
- java.awt.Image [] nativeObjects;
- java.awt.Image [] thumbnails = null;
try {
- nativeObjects = new BufferedImage [r.getNumImages (false)];
- for (int i = 0; i < nativeObjects.Length; i++) {
- if (r.hasThumbnails(i)) {
- if (thumbnails == null)
- thumbnails = new BufferedImage[nativeObjects.Length];
-
- thumbnails[i] = r.readThumbnail(i, 0);
- }
- nativeObjects [i] = r.read (i);
+ ic.NativeStream = input;
+ PlainImage pi = ic.ReadPlainImage();
+ base.Initialize( pi, false );
+
+ pi = ic.ReadNextPlainImage();
+ while ( pi != null) {
+ base.Initialize( pi, true );
+ pi = ic.ReadNextPlainImage();
}
+ _flags |= (int)(ImageFlags.ImageFlagsReadOnly | ImageFlags.ImageFlagsHasRealPixelSize);
}
- catch (Exception e) {
- //TDB: make exception same as in MS
- throw new ArgumentException ("Error reading", e);
+ catch (IOException ex) {
+ throw ex;
+ }
+ catch (Exception) {
+ throw new OutOfMemoryException ("Out of memory");
+ }
+ finally {
+ ic.Dispose();
}
- base.Initialize (nativeObjects, thumbnails, format, FrameDimension.Page.Guid);
}
-#if INTPTR_SUPPORT
- public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
- {
- throw new NotImplementedException();
- }
-#endif
#endregion
#region InternalSave
protected override void InternalSave (stream.ImageOutputStream output, Guid clsid) {
- string mime=ImageCodecInfo.FindEncoder (clsid).MimeType;
- imageio.ImageWriter writer = null;;
- try {
- writer = (imageio.ImageWriter) imageio.ImageIO.getImageWritersByMIMEType (mime).next ();
- writer.setOutput (output);
- if (NativeObjectsCount == 1)
- writer.write (NativeObject);
- else if (writer.canWriteSequence ())
- SaveSequence (writer);
- else
- throw new NotImplementedException ();
- }
- catch (Exception e) {
- //FIXME: check dotnet exceptions in save, and throw same types
- throw new Exception ("java threw an exception", e);
- }
- }
- void SaveSequence (imageio.ImageWriter writer) {
- //FIXME: does not supports metadata and thumbnails for now
- writer.prepareWriteSequence (null);
+ ImageCodec ic = ImageCodec.CreateWriter( clsid );
+ using (ic) {
+
+ PlainImage plainImage = CurrentImage;
+ plainImage.NativeImage.flush();
+
+ if ( ImageCodec.ClsidToImageFormat( clsid ).Equals( ImageFormat.Jpeg ) ) {
+ image.ColorModel cm = ((image.BufferedImage)CurrentImage.NativeImage).getColorModel();
+ if (cm.hasAlpha()) {
+ if (cm is image.DirectColorModel) {
+ image.Raster raster = ((image.BufferedImage)CurrentImage.NativeImage).getRaster();
+ image.DataBuffer db = raster.getDataBuffer();
+ image.DirectColorModel dcm = (image.DirectColorModel)cm;
+ image.SinglePixelPackedSampleModel jpegSampleModel = new image.SinglePixelPackedSampleModel(
+ db.getDataType(), Width, Height,
+ new int[] {dcm.getRedMask(), dcm.getGreenMask(), dcm.getBlueMask()} );
+
+ image.BufferedImage tb = new image.BufferedImage(
+ _jpegColorModel,
+ image.Raster.createWritableRaster( jpegSampleModel, db, null ),
+ false, null );
- for (int i = 0; i < NativeObjectsCount; i++) {
- imageio.IIOImage iio = new imageio.IIOImage ((BufferedImage)this[i], null, null);
- writer.writeToSequence (iio, null);
- }
+ plainImage = new PlainImage( tb, plainImage.Thumbnails, ImageFormat.Jpeg, plainImage.HorizontalResolution, plainImage.VerticalResolution, plainImage.Dimension );
+ plainImage.NativeMetadata = plainImage.NativeMetadata;
+ }
+ }
+ }
- writer.endWriteSequence ();
+ ic.NativeStream = output;
+ ic.WritePlainImage( plainImage );
+ }
}
#endregion
case PixelFormat.Indexed:
return BufferedImage.TYPE_BYTE_INDEXED;
default:
- return 0;
+ return BufferedImage.TYPE_INT_ARGB;
}
}
private static java.awt.Image CreateScaledImage(Image original, int width, int height) {
- JavaImage oldscaled = original.NativeObject.getScaledInstance(width, height,
+ JavaImage oldscaled = original.CurrentImage.NativeImage.getScaledInstance(width, height,
JavaImage.SCALE_DEFAULT);
BufferedImage newimage = new BufferedImage(oldscaled.getWidth(null),
oldscaled.getHeight(null),
#region Clone
public override object Clone () {
- return new Bitmap (this);
+ return new Bitmap ( (PlainImage)CurrentImage.Clone() );
}
- public Bitmap Clone (Rectangle rect, PixelFormat format)
+ public Bitmap Clone (Rectangle rect, PixelFormat pixFormat)
{
- BufferedImage sub = NativeObject.getSubimage(rect.X,rect.Y,rect.Width,rect.Height);
- return new Bitmap(sub, RawFormat, format);
+ return Clone(new RectangleF( rect.X, rect.Y, rect.Width, rect.Height ), pixFormat);
}
- public Bitmap Clone (RectangleF rect, PixelFormat format)
+ public Bitmap Clone (RectangleF rect, PixelFormat pixFormat)
{
- //TODO: check if there is more precise API
- BufferedImage sub = NativeObject.getSubimage((int)rect.X,(int)rect.Y,(int)rect.Width,(int)rect.Height);
- return new Bitmap(sub, RawFormat, format);
+ PlainImage plainImage = CurrentImage.Clone(false);
+ BufferedImage clone = new BufferedImage( (int)rect.Width, (int)rect.Height, ToBufferedImageFormat( pixFormat ) );
+ awt.Graphics2D g = clone.createGraphics();
+ try {
+ g.drawImage( NativeObject, -(int)rect.X, -(int)rect.Y, null );
+ }
+ finally {
+ g.dispose();
+ }
+
+ plainImage.NativeImage = clone;
+ return new Bitmap(plainImage);
}
#endregion
- #region LockBits [TODO]
+ #region LockBits
+ [MonoTODO]
public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) {
throw new NotImplementedException();
}
+
+#if NET_2_0
+ public
+#endif
+ BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData) {
+ throw new NotImplementedException();
+ }
#endregion
#region MakeTransparent
public void MakeTransparent ()
{
- Color clr = GetPixel(0,0);
+ Color clr = Color.FromArgb(0,0,0);
MakeTransparent (clr);
}
public void MakeTransparent (Color transparentColor)
{
- byte A = transparentColor.A;
image.WritableRaster raster = NativeObject.getRaster();
int numBands = raster.getNumBands();
+ if (numBands != 4)
+ return;
+
int maxWidth = raster.getWidth() + raster.getMinX();
int maxHeight = raster.getHeight() + raster.getMinY();
int[] srcPix = new int[numBands];
for (int y = raster.getMinY(); y < maxHeight; y++) {
for (int x = raster.getMinX(); x < maxWidth; x++) {
/*srcPix =*/ raster.getPixel(x, y, srcPix);
- for (int z = 0; z < numBands; z++) {
- int argb = srcPix[z];
- if ((uint)argb >> 24 == A) {
- argb &= 0x00FFFFFF;
- srcPix[z] = argb;
- }
+ if (srcPix[0] == transparentColor.R &&
+ srcPix[1] == transparentColor.G &&
+ srcPix[2] == transparentColor.B) {
+ srcPix[3] = 0;
+ raster.setPixel(x, y, srcPix);
}
}
}
}
#endregion
- #region SetResolution [TODO]
+ #region SetResolution
public void SetResolution (float xDpi, float yDpi)
{
- throw new NotImplementedException();
+ CurrentImage.HorizontalResolution = xDpi;
+ CurrentImage.VerticalResolution = yDpi;
}
#endregion
- #region UnlockBits [TODO]
+ #region UnlockBits
+ [MonoTODO]
public void UnlockBits (BitmapData bitmap_data)
{
throw new NotImplementedException();
#region NativeObject
internal new BufferedImage NativeObject {
get {
- return (BufferedImage)base.NativeObject;
+ return (BufferedImage)base.NativeObject.CurrentImage.NativeImage;
}
}
case 11://JavaImage.TYPE_USHORT_GRAY:
return PixelFormat.Format16bppGrayScale;
case 10://JavaImage.TYPE_BYTE_GRAY:
- return PixelFormat.Format1bppIndexed;
+ return PixelFormat.Format8bppIndexed;
case 1: //JavaImage.TYPE_INT_RGB
return PixelFormat.Format32bppRgb;
case 2: //JavaImage.TYPE_INT_ARGB:
return PixelFormat.Format16bppRgb565;
case 13://JavaImage.TYPE_BYTE_INDEXED:
return PixelFormat.Indexed;
- //TODO: support this
+ //TBD: support this
case 12://JavaImage.TYPE_BYTE_BINARY:
case 0://JavaImage.TYPE_CUSTOM:
case 4://JavaImage.TYPE_INT_BGR:
#endregion
#if INTPTR_SUPPORT
+ [MonoTODO]
public static Bitmap FromHicon (IntPtr hicon)
{
throw new NotImplementedException();
}
- public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested
+ [MonoTODO]
+ public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TBD: Untested
{
throw new NotImplementedException();
}
+ [MonoTODO]
public IntPtr GetHbitmap ()
{
throw new NotImplementedException();
}
+ [MonoTODO]
public IntPtr GetHbitmap (Color background)
{
throw new NotImplementedException();
}
+ [MonoTODO]
public IntPtr GetHicon ()
{
throw new NotImplementedException();