Rotate image and thumb - c#

I Want To Rotate image. I save My Image in Database
var fileInDB = GetFileFromDB();
var inputStream = new MemoryStream(fileInDB.FileData); // fileInDB.FileData is Byte[]
var image = Image.FromStream(streamInput);
image.RotateFlip(RotateFlipType.Rotate90FlipNone);
image.Save(streamOut, ImageFormat.Jpeg);
SaveFileToDB(streamOut.ToArray());
image rotate correctly. but its thumbnail dont rotate. it is code of create Thumb:
var fileInDB = GetFileFromDB();
var mainImage = Image.FromStream(new MemoryStream(fileInDB.Filedata));
int thumbWidth = 100;
int thumbHeight = (thumbWidth * mainImage.Height) / mainImage.Width;
var thumbImage = mainImage.GetThumbnailImage(thumbWidth, thumbHeight, null, IntPtr.Zero);

Related

How to add a text to existing image using skiasharp

I have existing image converted to base64 and I would like to add text on top of it. However this return only the original image. Could you please advise where am I making mistake?
var signatureData = Convert.FromBase64String(signature);
var stream = new MemoryStream(signatureData);
var signatureBitmap = SKBitmap.Decode(stream);
var canvas = new SKCanvas(signatureBitmap);
var origin = new SKPoint();
var paint = new SKPaint
{
TextSize = 10,
IsAntialias = true,
Color = SKColors.Black,
IsStroke = false
};
origin.X = 10;
origin.Y = 30;
paint.TextAlign = SKTextAlign.Left;
canvas.DrawText("text", origin, paint);
canvas.Flush();
var resultImage = SKImage.FromBitmap(signatureBitmap);
var data = resultImage.Encode(SKEncodedImageFormat.Png, 100);
return Convert.ToBase64String(data.ToArray());
This posted question actually worked for me, only the position was wrong so the text was very tiny

How to crop a captured screenshot?

Capturing a screen shot is quite easy but cropping is a different story, or at least appears so. We are attempting to emulate the solution here in Xamarin using SkiaSharp (System.Drawing not supported in Xamarin).
Currently we are able to capture the screenshot and return the image BUT if we crop our image the image returned is all black.
How do we crop a captured screenshot correctly?
NOTE*: image = image.Subset(rec); under the "crop image" section is how we are trying to crop.
iOS screenshot
public byte[] Capture()
{
var capture = UIScreen.MainScreen.Capture();
using (NSData data = capture.AsPNG())
{
var bytes = new byte[data.Length];
Marshal.Copy(data.Bytes, bytes, 0, Convert.ToInt32(data.Length));
return bytes;
}
}
Droid screenshot
public byte[] Capture()
{
var rootView = context.Window.DecorView.RootView;
using (var screenshot = Bitmap.CreateBitmap(
rootView.Width,
rootView.Height,
Bitmap.Config.Argb8888))
{
var canvas = new Canvas(screenshot);
rootView.Draw(canvas);
using (var stream = new MemoryStream())
{
screenshot.Compress(Bitmap.CompressFormat.Png, 90, stream);
return stream.ToArray();
}
}
}
Attempting to crop captured screenshot
// Use this function to crop a screen shot to a specific element.
public byte[] test(byte[] screenshotData, View element)
{
// locate IntPtr to byte[] of uncropped screenshot
GCHandle gch = GCHandle.Alloc(screenshotData, GCHandleType.Pinned);
IntPtr addr = gch.AddrOfPinnedObject();
// assign initial bounds
SKImageInfo info = new SKImageInfo((int)App.Current.MainPage.Width,
(int)App.Current.MainPage.Height);
// create initial pixel map
using SKPixmap pixmap = new SKPixmap(info, addr);
// Release
gch.Free();
// create bitmap
using SKBitmap bitmap = new SKBitmap();
// assign pixel data
bitmap.InstallPixels(pixmap);
// create surface
using SKSurface surface = SKSurface.Create(info);
// create a canvas for drawing
using SKCanvas canvas = surface.Canvas;
// draw
canvas.DrawBitmap(bitmap, info.Rect);
// get an image subset to save
SKImage image = surface.Snapshot();
SKRectI rec = new SKRectI((int)element.Bounds.Left, (int)element.Bounds.Top,
(int)element.Bounds.Right, (int)element.Bounds.Bottom);
// crop image
image = image.Subset(rec);
byte[] bytes = SKBitmap.FromImage(image).Bytes;
image.Dispose();
return bytes;
}
EDIT: Alternative solution attempt (not working)
// Use this function to crop a screen shot to a specific element.
public byte[] test(byte[] screenshotData, View element)
{
// locate IntPtr to byte[] of uncropped screenshot
GCHandle gch = GCHandle.Alloc(screenshotData, GCHandleType.Pinned);
IntPtr addr = gch.AddrOfPinnedObject();
// assign initial bounds
SKImageInfo info = new SKImageInfo((int)App.Current.MainPage.Width,
(int)App.Current.MainPage.Height);
// create bitmap
SKBitmap bitmap = new SKBitmap();
bitmap.InstallPixels(info, addr);
// boundaries
SKRect cropRect = new SKRect((int)element.Bounds.Left, (int)element.Bounds.Top,
(int)element.Bounds.Right, (int)element.Bounds.Bottom);
SKBitmap croppedBitmap = new SKBitmap((int)cropRect.Width,
(int)cropRect.Height);
SKRect dest = new SKRect(0, 0, cropRect.Width, cropRect.Height);
SKRect source = new SKRect(cropRect.Left, cropRect.Top,
cropRect.Right, cropRect.Bottom);
// draw with destination and source rectangles
// to extract a subset of the original bitmap
using SKCanvas canvas = new SKCanvas(croppedBitmap);
canvas.DrawBitmap(bitmap, source, dest);
return croppedBitmap.Bytes;
//return bitmap.Bytes;
}
iOS solution - As seen here.
// crop the image, without resizing
private UIImage CropImage(UIImage sourceImage, int crop_x, int crop_y, int width, int height)
{
var imgSize = sourceImage.Size;
UIGraphics.BeginImageContextWithOptions(new System.Drawing.SizeF(width, height), false, 0.0f);
var context = UIGraphics.GetCurrentContext();
var clippedRect = new RectangleF(0, 0, width, height);
context.ClipToRect(clippedRect);
var drawRect = new RectangleF(-crop_x, -crop_y, imgSize.Width, imgSize.Height);
sourceImage.Draw(drawRect);
var modifiedImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return modifiedImage;
}
Android solution - getNavigationBarSize(context) as seen here
// crop the image, without resizing
private byte[] CropImage(byte[] screenshotBytes, int top)
{
Android.Graphics.Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeByteArray(
screenshotBytes, 0, screenshotBytes.Length);
int viewStartY = (int)(top * 2.8f);
int viewHeight = (int)(bitmap.Height - (top * 2.8f));
var navBarXY = getNavigationBarSize(context);
int viewHeightMinusNavBar = viewHeight - navBarXY.Y;
Android.Graphics.Bitmap crop = Android.Graphics.Bitmap.CreateBitmap(bitmap,
0, viewStartY,
bitmap.Width, viewHeightMinusNavBar
);
bitmap.Dispose();
using MemoryStream stream = new MemoryStream();
crop.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, stream);
return stream.ToArray();
}
*NOTE: Unsure why a multiplication of 2.8 is required, though this works correctly. It should be stated testing was only done in the Android emulator. Perhaps it's emulator specific.
*NOTE2: x = 0 and width is equal to the entire width of the screen as that's per our requirement. Likewise top is Element.Bounds.Top.

ImageResizer generate wrong width for the image

I let users upload a banner with a minimum width of 400px. This image will then get a wide of 1110px.
I try to upload images with the following sizes: 960x390, 410x410, 784x250.
When i upload 784x250, the image get the same size 784x250 not the width, 1110px.
I use this:
int Height;
using (var Bmp = new Bitmap(str))
{
if (Bmp.Width < 400)
{
throw;
}
if (Bmp.Height < 150)
{
throw;
}
Height = Bmp.Height;
}
if (Height > 300)
{
Height = 300;
}
str.Position = 0;
var ImageData = str.StreamToByteArray();
var Settings = "width=1110;height="+ Height + ";format=jpg;mode=crop;"
var Setting = new ResizeSettings(Settings);
using (var Out = new MemoryStream())
{
using (var In = new MemoryStream(ImageData))
{
In.Seek(0, SeekOrigin.Begin);
var I = new ImageJob(In, Out, Setting)
{
CreateParentDirectory = false
};
I.Build();
}
Out.Position = 0;
// Upload to blob
}
(str contains a stream with the image)
I want the image to be 1110px wide and max 300px high.
Whats wrong?
ImageResizer does not upscale images unless you specifically ask for it via scale=both or scale=canvas. Upscaling is typically undesired.
Also, you can pass the stream directly to ImageJob and simplify your code significantly.
str.Seek(0, SeekOrigin.Begin);
var Out = new MemoryStream(8096);
new ImageJob(str, Out, new Instructions("width=1110;height="+ Height + ";format=jpg;mode=crop;scale=both")).Build();
Out.Seek(0, SeekOrigin.Begin);
The other sizes you tested each have a Bmp.Height > 300 which means the image requires to be cropped.
However when using an image size 784x250, the image doesn't require to be cropped. So you'll never re-size the image.
Assuming you wish to keep the image proportionally correct, you should first re-size the image to match the wanted width and afterwards crop the exceeding height if necessary.
var image = new Bitmap(str);
var ratio = (double)1110 / image.Width;
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
var newImage = new Bitmap(newWidth, newHeight);
Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
var bmp = new Bitmap(newImage);
if(bmp.Height > 300){
//Resize again using crop, like you did in your original code.
}

Resize byte[] of Image

After reading from file dialog I want to resize a picture. I have the done the following code. Now I want to resize the stream of picture. How do I do it?
Stream stream = (Stream)openFileDialog.File.OpenRead();
byte[] bytes = new byte[stream.Length];
There is no need to declare a byte[], to resize an image just use
Image image = Image.FromFile(fileName);
check this other answer to see how to scale the image aftewards
try this
public static Image ScaleImage(Image image, int maxWidth, int maxHeight)
{
var ratioX = (double)maxWidth / image.Width;
var ratioY = (double)maxHeight / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
var newImage = new Bitmap(newWidth, newHeight);
Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
return newImage;
}
Usage
Image img = Image.FromStream(stream);
Image thumb = ScaleImage(img);
stream.Close();
stream.Dispose();
stream = new MemoryStream();
thumb.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
I have an picturebox. I load an image, resizing and conveting to byte at last sending to sqllite. Maybe it can be hlepfıull to you Code is below.
private static byte[] byteResim = null;
private void btnResimEkle_Click(object sender, EventArgs e)
{
openFileDialog1.Title = "Resimdosyası seçiniz.";
openFileDialog1.Filter = "Resim files (*.jpg)|*.jpg|Tüm dosyalar(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string resimYol = openFileDialog1.FileName; // File name of the image
picResim.Image = Image.FromFile(resimYol);// picResim is name of picturebox
picResim.Image = YenidenBoyutlandir(new Bitmap(picResim.Image)); //this method resizing the image
Image UyeResim = picResim.Image; // and this four block converting to image to byte
MemoryStream ms = new MemoryStream();
UyeResim.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byteResim = ms.ToArray(); // byteResim variable format Byte[]
}
}
Image YenidenBoyutlandir(Image resim)// resizing image method
{
Image yeniResim = new Bitmap(150, 156);
using (Graphics abc = Graphics.FromImage((Bitmap)yeniResim))
{
abc.DrawImage(resim, new System.Drawing.Rectangle(0, 0, 150, 156));
}
return yeniResim;
}

Silverlight Resize Image and Final File Size

I build a file uploader using silverlight and http://imagetools.codeplex.com/.
Its all ok, but my final file is about 300KB(size) with an 400 x 300(resolution).
When i open it on MS Paint and Save It as jpg again the size is set to normal.
my suspect is de enconde o file is a (png) but i don't now how.
My Code:
public static byte[] resize(string extension,int width,int height,int orientation)
{
//Decoders.AddDecoder<BmpDecoder>();
//Decoders.AddDecoder<PngDecoder>();
Decoders.AddDecoder<JpegDecoder>();
//Decoders.AddDecoder<GifDecoder>();
var newImg = new ExtendedImage();
if (orientation == 0)
newImg = ExtendedImage.Resize(img, width, height, new ImageTools.Filtering.NearestNeighborResizer());
else
newImg = ExtendedImage.Resize(img, height, width, new ImageTools.Filtering.NearestNeighborResizer());
//newImg = applyWaterMark(newImg);
//var s = new MemoryStream();
var s = newImg.ToStreamByExtension(extension);
return ReadFully(s);
}
solved!!
var e = new ImageTools.IO.Jpeg.JpegEncoder();
var s = new MemoryStream(); e.Quality = 90;
e.Encode(newImg,s);
//var s = newImg.ToStream();
return s.GetBuffer();

Categories