loading bitmap from application folder - c#

i am using the below code to load a .png file to bitmap
Bitmap original;
if (tbp.LanguageTypingdir =="LTR")
{
original = new Bitmap(#"Images\CC_Logo.png");
}
else
{
original = new Bitmap(#"Images\CC_Logo_ar.png");
}
i get error Additional information: Parameter is not valid.

I don't know about yours, but I know the following syntax works for loading a bitmap image:
Image img = Bitmap.FromFile("C:/Users/xxx/Pictures/1.jpg");
If you need to work on the Bitmap class, just cast the Image object.
Bitmap myBitmap = img as Bitmap;

Related

Bitmap object needed in MAUI.NET?

I need to store a bitmap object in my MAUI.NET application.
To be clear - in my definition: bitmap is a representation of the image by the 2 dimensional array of pixels, that have at least R,G and B value.
In .NET 4.7 it wasn't already such an object, but there was a NuGet System.Drawings.Common that allowed me to use such an object.
How to handle such a situation in MAUI.NET?
edit:
Sorry if I wasn't clear. This is my scenario:
I am not about drawing and image in UI.
I want to let user specify path to file and then I need to have a Bitmap of this picture/image, because I need to pass it to different layers/project -> pass it to algorithms with the logic that would process it.
So this would be a code I would do in .NET Framework 4...:
string filepath = someFileSystemDialog.Result;
Bitmap bitmap = new Bitmap(filepath); // here is the problem, in previous .NET there was Bitmap object wchich was perfect, here is lack
Bitmap processedBitmap = MyOtherProjectWithLogicAlgorithms.ProcessAnImage(bitmap);
processedBitmap.Save(finalOutputPath, ImageFormat.Png);
But in Maui.NET from a filedialog I managed to get something like below:
var fileResult = await FilePicker.Default.PickAsync(...);
if(fileResult != null)
{
ImageSource is = ImageSource.FromFile(fileResult.FullPath);
Bitmap bm = ??(is); // how to get Bitmap from an ImageSource ?
MyOtherProjectWithLogicAlgorithms is an other .NET project that (for compatibility would also have .NET 6.0) - I guess this is required to work with MAUI.NET as dependency project.
There is Bitmap but seems that is dedicated only to Android:
Android.Graphics.Bitmap - Can I use it in general code for all the platforms?
edit:
The solution is SkiaSharp. Look into comments below for an alternative.
If I understand your means correctly, you can paint graphical objects in the Microsoft.Maui.Graphics namespace .
First,Images can be drawn on an ICanvas using the DrawImage method, which requires an IImage argument, and x, y, width, and height arguments, of type float.
The following example shows how to load an image and draw it to the canvas:
using Microsoft.Maui.Graphics.Platform;
...
IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
image = PlatformImage.FromStream(stream);
}
if (image != null)
{
canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
For more information, you can check: Draw an image .
Second, you can also paint an image.The ImagePaint class, that's derived from the Paint class, is used to paint a graphical object with an image.
The ImagePaint class defines an Image property, of type IImage, which represents the image to paint. The class also has an IsTransparent property that returns false.
To paint an object with an image, load the image and assign it to the Image property of the ImagePaint object.
The following example shows how to load an image and fill a rectangle with it:
using Microsoft.Maui.Graphics.Platform;
...
IImage image;
var assembly = GetType().GetTypeInfo().Assembly;
using (var stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
image = PlatformImage.FromStream(stream);
}
if (image != null)
{
ImagePaint imagePaint = new ImagePaint
{
Image = image.Downsize(100)
};
canvas.SetFillPaint(imagePaint, RectF.Zero);
canvas.FillRectangle(0, 0, 240, 300);
}
For more details, you can check: Paint graphical objects

WPF: Image control of a CroppedBitmap as BitmapImage is still uncropped Image (Conversion Problem?)

I am trying to Crop a BitmapImage in my WPF application StageWindow.Stage using the CroppedBitmap class.
When saving the new cropped image to file JpegBitmapEncoder I can see the correctly cropped image. CroppedBitmap Crop
However I actually want to save the cropped image into a List\<BitmapImage\> for later use in another WPF image control. That list contains BitmapImages already so changing it to CroppedBitmaps would not suffice.
to be able to store the new croppedBitmap I use something like this:
BitmapImage xx = CroppedBitmap1 as BitmapImage;
when setting an WPF image control to the new BitmapImage (ExpectedCroppedImage) it still displays the CroppedBitmaps original source image without the crop.
I suspect the code above to delete the crop attribute from the new BitmapImage because the BitmapImage itself has no attributes for the cropped Area. But how can I save only the cropped part into a new BitmapImage?
I have been searching around but it seems CroppedBitmap should do the trick I just dont know how to convert it back in the correct manner.
Here is the Code for clarification:
//Stage is the WPF image element that im reading the source image from.
ImageSource StageWindowImageSource = StageWindow.Stage.Source;
CroppedBitmap Crop = new CroppedBitmap((BitmapSource)StageWindowImageSource, new Int32Rect(0,0,50,50));
ExpectedCroppedImage = Crop.Source as BitmapImage;
JpegBitmapEncoder jpg = new JpegBitmapEncoder();
jpg.Frames.Add(BitmapFrame.Create(Crop));
FileStream fp = new FileStream("F:/Crop.jpg", FileMode.Create, FileAccess.Write);
jpg.Save(fp);
fp.Close();
The line
ExpectedCroppedImage = Crop.Source as BitmapImage;
does not return the cropped bitmap, but the original one from which the crop was taken, i.e. the Source bitmap.
Besides that, you don't need any conversion from CroppedBitmap to BitmapImage.
Instead, use a base class of BitmapImage and CroppedBitmap as element type of the List, i.e. use a List<BitmapSource> or List<ImageSource> for your collection.
Now you can assign instances of any class derived from the element type.
List<BitmapSource> images = ...
CroppedBitmap croppedImage = new CroppedBitmap(...);
images.Add(croppedImage);
BitmapImage someOtherImage = new BitmapImage(...);
images.Add(someOtherImage);
private void MyMethod()
{
ImageSource StageWindowImageSource = img.Source;
CroppedBitmap Crop = new CroppedBitmap((BitmapSource) StageWindowImageSource, new Int32Rect(20, 20, 150, 110));
img2.Source = GetImage(Crop, new JpegBitmapEncoder());
}
private BitmapImage GetImage(BitmapSource source, BitmapEncoder encoder)
{
var image = new BitmapImage();
using (var sourceMs = new MemoryStream())
{
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(sourceMs);
sourceMs.Position = 0;
using (var destMs = new MemoryStream(sourceMs.ToArray()))
{
image.BeginInit();
image.StreamSource = destMs;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();
image.Freeze();
}
}
return image;
}

I can not solve - A Graphics object cannot be created from an image that has an indexed pixel format error

I am trying this example but I got "Source pixel format is not supported by the filter" error, and to solve it I tried with these answeres but I got titled error, then I tried to solve it with these answers.
But I am out of luck and I keep getting this error.
Can anyone give me a solution?
Heres the code:
// Open your image
string path = "sample2.jpg"; //taken from first example links initial image.
Bitmap image = (Bitmap)Bitmap.FromFile(path);
// The original bitmap with the wrong pixel format.
// You can check the pixel format with originalBmp.PixelFormat
//Bitmap originalBmp = new (Bitmap)Image.FromFile("YourFileName.gif");
// Create a blank bitmap with the same dimensions
Bitmap tempBitmap = new Bitmap(image.Width, image.Height);
// From this bitmap, the graphics can be obtained, because it has the right PixelFormat
using (Graphics g = Graphics.FromImage(tempBitmap))
{
// Draw the original bitmap onto the graphics of the new bitmap
g.DrawImage(image, 0, 0);
// Use g to do whatever you like
//g.DrawLine(...);
}
//Bitmap EditableImg = new Bitmap(image);
Bitmap a = AForge.Imaging.Image.Clone(tempBitmap, PixelFormat.Format8bppIndexed); //currently getting titled error here.
AForge.Imaging.Image.SetGrayscalePalette(a);
// create filter
DifferenceEdgeDetector filter = new DifferenceEdgeDetector();
// apply the filter
filter.ApplyInPlace(image);
error image for reference:

Update PNG Image at runtime throws GDI+ overflow exception

I've made a ListBox with items that have an image bound to them (Binding BitmapSource, UpdateSourceTrigger=PropertyChanged). They updated at runtime and all was fine but their background was black and not Transparent as i wished for.
Now i want to have the same functionality with PNG.
So now I did bind to the URI of the PNG and tried to change the image and notify afterwards, but i get an error (probably because i want to save an image while its already open?)
I'll try my best to show all the relevant code:
XAML:
<Image Source="{Binding Path=OutfitImageString, UpdateSourceTrigger=PropertyChanged}"/>
C# URI string, I wanted to use this to tell when the PNG was changed:
private string _OutfitImageString;
public string OutfitImageString
{
get { return _OutfitImageString; }
set
{
_OutfitImageString = value;
NotifyPropertyChanged("OutfitImageString");
}
}
And every time I change the Bitmap picture (its bound to an instance of a class) I run this method:
public void UpdateImage()
{
// new bitmap (transparent background by default)
Bitmap nb = new Bitmap(100, 110, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// [ ... ] Create the Bitmap
// save to PNG to get a transparent background, every Person has a unique name
string saveAt = Directory.GetCurrentDirectory() + Name + "_outfit.png";
nb.Save(saveAt, System.Drawing.Imaging.ImageFormat.Png);
// notify that we changed the image (even tho the URI string is the same)
OutfitImageString = saveAt;
}
This line creates an Error, as soon as it is run for a 2. time:
nb.Save(saveAt, System.Drawing.Imaging.ImageFormat.Png);
Exception type -2147467259 Allgemeiner Fehler in GDI+. overflow excpetion: System.Runtime.InteropServices.ExternalException (0x80004005): Allgemeiner Fehler in GDI+. bei System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) bei System.Drawing.Image.Save(String filename, ImageFormat format)
I stored the BitmapSource of the Bitmap before and Bound to that aswell, this used to work perfectly (just the background was not transparent).
Also since these images are kind of temporary, I don't like saving them all the time :/
Thanks for the help, I am sorry the description is kinda messy... Just write if you need further details!
It is not at all necessary to save a bitmap file.
Change the type of your property from string to ImageSource
private ImageSource _OutfitImage;
public ImageSource OutfitImage
{
get { return _OutfitImage; }
set
{
_OutfitImage = value;
NotifyPropertyChanged(nameof(OutfitImage));
}
}
and bind to it like shown below (where setting UpdateSourceTrigger=PropertyChange is pointless).
<Image Source="{Binding Path=OutfitImage}"/>
Then assign a value like this:
OutfitImage = BitmapToBitmapSource(nb);
...
public static BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap bitmap)
{
var bitmapImage = new BitmapImage();
using (var stream = new MemoryStream())
{
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
}
return bitmapImage;
}

The input image lost its PixelFormat during the loading process. c#

I want to load an image from my resources to a Bitmap, and save its Pixel Format. The input image is a .bmp file with 8 BitsPerPixel image depth. This is the code:
Bitmap inputImage = new Bitmap(Test.Resources.sourceImage);
When I debug the program and I check the properties of the sourceImage, its PixelFormat is PixelFormat.Format8bppIndexed.
But after this variable assignment the PixelFormat of inputImage is Format32bppArgb.
Do you have any idea where is the problem?
var source = Test.Resources.sourceImage;
Bitmap inputImage = source.Clone(new Rectangle(Point.Empty, source.Size), source.PixelFormat);

Categories