Is anyone able to help me translate this method in ios to mac version? Code is written in C# in Xamarin
public static UIImage GetImageFromColor(UIColor color, float borderWidth = 1.0f)
{
var rect = new CGRect(0.0f, 0.0f, borderWidth, borderWidth);
UIGraphics.BeginImageContext(rect.Size);
var context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image.CreateResizableImage(new UIEdgeInsets(1.0f, 1.0f, 1.0f, 1.0f));
}
UIGraphics.BeginImageContext translates to a CGBitmapContext (or CGContext depending upon what you need).
So to fill a CGBitmapContext with a color:
var size = new CGSize(width, height);
var rect = new CGRect(new CGPoint(), size);
NSImage image;
using (var context = new CGBitmapContext(IntPtr.Zero, width, height, 8, width * 4, NSColorSpace.GenericRGBColorSpace.ColorSpace, CGImageAlphaInfo.PremultipliedFirst))
{
context.SetFillColor(NSColor.Red.CGColor);
context.FillRect(rect);
using (var cgImage = context.ToImage())
{
image = new NSImage(cgImage, size);
}
}
Note: You should use using or make sure that you Dispose of the context and CGImage to avoid a memory leak
This is not a translation from the code you posted but it does exactly the same job:
public static NSImage GetImageFromColor (NSColor color, float borderWidth = 1.0f)
{
var image = new NSImage (new CGSize (borderWidth, borderWidth));
image.LockFocus ();
color.DrawSwatchInRect (new CGRect (new CGPoint (0, 0), image.Size));
image.UnlockFocus ();
return image;
}
Hope this helps.-
Related
I save images from social networks and I want to do rounded corners for image and save it to the database. For example, I got a photo from the facebook by url on my Api and I want to process this image
How it possible on .net Core
Below, what results I expect
Image before:
Image after:
You can use SixLabors.ImageSharp library, it is available for .NET Core:
PM > Install-Package SixLabors.ImageSharp
Here is the sample code:
public static void ApplyRoundedCorners(Image<Rgba32> img, float cornerRadius)
{
IPathCollection corners = BuildCorners(img.Width, img.Height, cornerRadius);
var graphicOptions = new GraphicsOptions(true) { BlenderMode = PixelBlenderMode.Src };
img.Mutate(x => x.Fill(graphicOptions, Rgba32.Transparent, corners));
}
public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
{
var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
IPath cornerToptLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
var center = new Vector2(imageWidth / 2F, imageHeight / 2F);
float rightPos = imageWidth - cornerToptLeft.Bounds.Width + 1;
float bottomPos = imageHeight - cornerToptLeft.Bounds.Height + 1;
IPath cornerTopRight = cornerToptLeft.RotateDegree(90).Translate(rightPos, 0);
IPath cornerBottomLeft = cornerToptLeft.RotateDegree(-90).Translate(0, bottomPos);
IPath cornerBottomRight = cornerToptLeft.RotateDegree(180).Translate(rightPos, bottomPos);
return new PathCollection(cornerToptLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
}
private static IImageProcessingContext<Rgba32> ConvertToAvatar(this IImageProcessingContext<Rgba32> processingContext, Size size, float cornerRadius)
{
return processingContext.Resize(new ResizeOptions
{
Size = size,
Mode = ResizeMode.Crop
}).Apply(i => ApplyRoundedCorners(i, cornerRadius));
}
And you can use it like this:
using (var img = Image.Load("fb.jpg"))
{
using (Image<Rgba32> destRound = img.Clone(x => x.ConvertToAvatar(new Size(200, 200), 100)))
{
destRound.Save("output/fb-round.png");
}
}
More examples can be found here.
I have an image that is 646x289 that I am trying to fit in the screen with respect to its aspect ratio.
Here is my current approach:
Controller:
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
_imnLogo.ContentMode = UIViewContentMode.ScaleAspectFit;
_imnLogo.SizeToFit();
_imnLogo.Frame = new CGRect(
View.Bounds.Left + 2 * Globals.MarginGrid,
View.Bounds.Top + Globals.MarginGrid,
_scaledImage.Size.Width, _scaledImage.Size.Height);
}
public override void LoadView()
{
base.LoadView();
_scaledImage = MaxResizeImage(
UIImage.FromFile("imn_logo.png"), (float) View.Bounds.Width, (float) View.Bounds.Height);
_imnLogo = new UIImageView(_scaledImage);
View.AddSubview(_imnLogo);
}
public UIImage MaxResizeImage(UIImage sourceImage, float maxWidth, float maxHeight)
{
var sourceSize = sourceImage.Size;
var maxResizeFactor = Math.Max(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
if (maxResizeFactor > 1) return sourceImage;
var width = maxResizeFactor * sourceSize.Width;
var height = maxResizeFactor * sourceSize.Height;
UIGraphics.BeginImageContext(new SizeF((float) width, (float) height));
sourceImage.Draw(new RectangleF(0, 0, (float) width, (float) height));
var resultImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return resultImage;
}
When this loads, the image is way too large and doesn't fit in the screen.
I am constructing all of my interfaces in C# (using Xamarin) as well so I need to be able to do this using frames and bounds.
Use the ContentMode of the UIImageView to control how the image is scaled and you can skip the manual resizing:
public override void LoadView()
{
base.LoadView();
_imnLogo = new UIImageView(UIImage.FromFile("imn_logo.png"));
_imnLogo.Frame = View.Frame;
_imnLogo.ContentMode = UIViewContentMode.ScaleAspectFill;
View.AddSubview(imageView);
View.SendSubviewToBack(imnLogo); // Do this if you want to place other `View`s on top of the logo...
}
Ref: https://developer.apple.com/reference/uikit/uiviewcontentmode
I have some code that adds text to a bitmap. This works well unless the text is wider than the original image.
How do I go about making the image wide enough for my text to display correctly?
Here is my code:
private BitmapDescriptor GetCustomBitmapDescriptor(string text)
{
Bitmap baseBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.Icon);
Bitmap bitmap = baseBitmap.Copy(Bitmap.Config.Argb8888, true);
Paint paint = new Paint(PaintFlags.AntiAlias);
Rect bounds = new Rect();
paint.GetTextBounds(text, 0, text.Length, bounds);
float bitmapMiddle = bitmap.Width / 2.0f;
Canvas canvas = new Canvas(bitmap);
canvas.DrawText(text, bitmapMiddle - (bounds.Right / 2.0f), bitmap.Height, paint);
BitmapDescriptor icon = BitmapDescriptorFactory.FromBitmap(bitmap);
return (icon);
}
Thanks in advance.
Just color code and it is working
private Bitmap GetCustomBitmapDescriptor(String text)
{
Bitmap baseBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launche);
Bitmap bitmap = baseBitmap.copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
float bitmapMiddle = bitmap.getWidth() / 2.0f;
Canvas canvas = new Canvas(bitmap);
paint.setColor(Color.RED);
canvas.drawText(text, bitmapMiddle - (bounds.right / 2.0f), bitmap.getHeight(), paint);
return bitmap;
}
I'm trying to capture a screenshot of a gameobject in Unity3D Pro so that it has a transparent background. This script was suggested to me and it works, when connected to the main Camera, as long as the material doesn't have a texture. Then I get a semi transparency appearing on the gameobject as shown in this example. http://sta.sh/0iwguk5rx61. Any help with this would be greatly appreciated.
public int resWidth = 2550;
public int resHeight = 3300;
private bool takeHiResShot = false;
public static string ScreenShotName(int width, int height) {
return string.Format("{0}/screen_{1}x{2}_{3}.png",
Application.dataPath,
width, height,
System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
}
public void TakeHiResShot() {
takeHiResShot = true;
}
void LateUpdate() {
takeHiResShot |= Input.GetKeyDown("k");
if (takeHiResShot)
{
RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
camera.targetTexture = rt;
Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.ARGB32, false);
camera.Render();
RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
camera.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
byte[] bytes = screenShot.EncodeToPNG();
string filename = ScreenShotName(resWidth, resHeight);
System.IO.File.WriteAllBytes(filename, bytes);
Debug.Log(string.Format("Took screenshot to: {0}", filename));
Application.OpenURL(filename);
takeHiResShot = false;
}
}
sdg
See if this works for you.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class Screenshot : MonoBehaviour
{
private void Start()
{
string filename = string.Format("Assets/Screenshots/capture_{0}.png", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff"));
if (!Directory.Exists("Assets/Screenshots"))
{
Directory.CreateDirectory("Assets/Screenshots");
}
TakeTransparentScreenshot(Camera.main, Screen.width, Screen.height, filename);
}
public static void TakeTransparentScreenshot(Camera cam, int width, int height, string savePath)
{
// Depending on your render pipeline, this may not work.
var bak_cam_targetTexture = cam.targetTexture;
var bak_cam_clearFlags = cam.clearFlags;
var bak_RenderTexture_active = RenderTexture.active;
var tex_transparent = new Texture2D(width, height, TextureFormat.ARGB32, false);
// Must use 24-bit depth buffer to be able to fill background.
var render_texture = RenderTexture.GetTemporary(width, height, 24, RenderTextureFormat.ARGB32);
var grab_area = new Rect(0, 0, width, height);
RenderTexture.active = render_texture;
cam.targetTexture = render_texture;
cam.clearFlags = CameraClearFlags.SolidColor;
// Simple: use a clear background
cam.backgroundColor = Color.clear;
cam.Render();
tex_transparent.ReadPixels(grab_area, 0, 0);
tex_transparent.Apply();
// Encode the resulting output texture to a byte array then write to the file
byte[] pngShot = ImageConversion.EncodeToPNG(tex_transparent);
File.WriteAllBytes(savePath, pngShot);
cam.clearFlags = bak_cam_clearFlags;
cam.targetTexture = bak_cam_targetTexture;
RenderTexture.active = bak_RenderTexture_active;
RenderTexture.ReleaseTemporary(render_texture);
Texture2D.Destroy(tex_transparent);
}
}
You might have to refresh your assets folder (Ctrl+R) to make Screenshots folder appear in the inspector.
I am Colombian , and my English is not good, I hope you understand me,
I had the same problem and solved it by just changing the TextureFormat ARGB32 to RGB24:
...
RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
camera.targetTexture = rt;
Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
camera.Render();
RenderTexture.active = rt;
...
I hope to be helpful
see u, :D
I have a control (picturebox), in which I want to draw an 2D image with the help of DirectX.
I have a display and sprite, and it works fine.
// Some code here...
_device = new Device(0, DeviceType.Hardware, pictureBox1,
CreateFlags.SoftwareVertexProcessing,
presentParams);
_sprite = new Sprite(_device);
// ...
_sprite.Draw(texture, textureSize, _center, position, Color.White);
The problem is that texture size is much larger than picturebox, and I just want to find the way to fit it there.
I tried to set device.Transform property but it doesn't help:
var transform = GetTransformationMatrix(textureSize.Width, textureSize.Height);
_device.SetTransform(TransformType.Texture0, transform);
Here is GetTransform method:
Matrix GetTransformationMatrix(float width, float height)
{
var scaleWidth = pictureBox1.Width /width ;
var scaleHeight = pictureBox1.Height / height;
var transform = new Matrix();
transform.M11 = scaleWidth;
transform.M12 = 0;
transform.M21 = 0;
transform.M22 = scaleHeight;
return transform;
}
Thanks for any solution || help.
The solution was just to use this:
var transformMatrix = Matrix.Scaling(scaleWidth, scaleHeight, 0.0F);
instead of hand-made method.