How do you resize a Bitmap under .NET CF 2.0 - graphics

I have a Bitmap that I want to enlarge programatically to ~1.5x or 2x to its original size. Is there an easy way to do that under .NET CF 2.0?

One "normal" way would be to create a new Bitmap of the desired size, create a Graphics for it and then draw the old image onto it with Graphics.DrawImage(Point, Rectangle). Are any of those calls not available on the Compact Framework?
EDIT: Here's a short but complete app which works on the desktop:
using System;
using System.Drawing;
class Test
{
static void Main()
{
using (Image original = Image.FromFile("original.jpg"))
using (Bitmap bigger = new Bitmap(original.Width * 2,
original.Height * 2,
original.PixelFormat))
using (Graphics g = Graphics.FromImage(bigger))
{
g.DrawImage(original, new Rectangle(Point.Empty, bigger.Size));
bigger.Save("bigger.jpg");
}
}
}
Even though this works, there may well be better ways of doing it in terms of interpolation etc. If it works on the Compact Framework, it would at least give you a starting point.

The CF has access to the standard Graphics and Bitmap objects like the full framework.
Get the original image into a Bitmap
Create a new Bitmap of the desired size
Associate a Graphics object with the NEW Bitmap
Call g.DrawImage() with the old image and the overload to specify width/height
Dispose of things
Versions:
.NET Compact Framework
Supported in: 3.5, 2.0, 1.0

Related

Convert ConstraintLayout to image

I try to capture an image of all the elements inside my constaintLayout and then save it to the device.
I have done it on my iOS app, by capturing a UIView to an image with this simple line:
let theImage = self.myView.asImage()
Can I do something similar in Android Studio using Kotlin? Or is there any other layout/view better than constaintLayout that works like uiView in iOS?
Shameless copy and automatic to-kotlin conversion (litterally pasting the java code into a kotlin file in Android Studio) of https://stackoverflow.com/a/34272518/4265739
private fun createBitmapFromView(context: Context, view: View): Bitmap {
val displayMetrics = DisplayMetrics()
(context as Activity).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics)
view.setLayoutParams(LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT))
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels)
view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
view.buildDrawingCache()
val bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
view.draw(canvas)
return bitmap
}
You can use the function above to create a bitmap containing the contents of the ConstraintLayout. In fact it should work for any View.
ConstraintLayout is the recommended layout to use in android. I cant tell if it works like iuView in IOS, but it is the Android way to do things.

How to resize image after being uploaded in ASP.NET Core 2.0

I want to resize an image and save this image multiple times with different sizes into a folder. I have tried ImageResizer or CoreCompat.System.Drawing but these libraries not compatible with .Net core 2. I have searched a lot of about this but i can't find any proper solution.
like in MVC4 i have used as:
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null)
{
var versions = new Dictionary<string, string>();
var path = Server.MapPath("~/Images/");
//Define the versions to generate
versions.Add("_small", "maxwidth=600&maxheight=600&format=jpg";);
versions.Add("_medium", "maxwidth=900&maxheight=900&format=jpg");
versions.Add("_large", "maxwidth=1200&maxheight=1200&format=jpg");
//Generate each version
foreach (var suffix in versions.Keys)
{
file.InputStream.Seek(0, SeekOrigin.Begin);
//Let the image builder add the correct extension based on the output file type
ImageBuilder.Current.Build(
new ImageJob(
file.InputStream,
path + file.FileName + suffix,
new Instructions(versions[suffix]),
false,
true));
}
}
return RedirectToAction("Index");
}
but in Asp.Net core 2.0 i am stuck. i have no idea how can i implement this in .Net core 2. Any one please can help me.
.NET Core 2.0 ships with System.Drawing.Common, which is the official implementation of System.Drawing for .NET Core.
Instead of CoreCompat.System.Drawing, can you try to install System.Drawing.Common and check whether that works?
You could get nuget package SixLabors.ImageSharp (do not forget to tick "Include prereleases" since now they have only beta) and use they library like this. Their GitHub
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
// Image.Load(string path) is a shortcut for our default type.
// Other pixel formats use Image.Load<TPixel>(string path))
using (Image<Rgba32> image = Image.Load("foo.jpg"))
{
image.Mutate(x => x
.Resize(image.Width / 2, image.Height / 2)
.Grayscale());
image.Save("bar.jpg"); // Automatic encoder selected based on extension.
}
Image processing in .NET Core : https://blogs.msdn.microsoft.com/dotnet/2017/01/19/net-core-image-processing/
Imageflow.NET Server is the .NET Core equivalent to ImageResizer, but is much faster and produces much smaller image files. See https://github.com/imazen/imageflow-dotnet-server
If you are just resizing during upload, or want to write your own middleware, use Imageflow.NET directly. See https://github.com/imazen/imageflow-dotnet
[Disclaimer: I am the author of both ImageResizer and Imageflow]

Dimensions of ImageMarker

I am new to Vuforia SDK. I have an image which acts as a target. I want to place this image on to the Imagemarker. In real time the size of the Imagemarker varies. Is there any method where I can get the width and height of the Imagemarker so that the target image fits exactly on the Imagemarker?
Since you did not specify if you are using the Unity or native APIs I will assume you are using Unity.
This is how you would go about it using the Vuforia API, placing this in a script attached to your ImageTarget GameObject.
IEnumerator Start()
{
Vuforia.ImageTarget img = GetComponent<Vuforia.ImageTargetBehaviour>().ImageTarget;
// This is rounded of in the console display,
// so individual components are printed afterwards
Debug.Log(img.GetSize());
Debug.Log(img.GetSize().x);
Debug.Log(img.GetSize().y);
Debug.Log(img.GetSize().z);
}
Alternatively you can directly use the Bounds of the renderer.
void Start()
{
Renderer r = GetComponent<Renderer>();
Debug.Log(r.bounds.size.x);
Debug.Log(r.bounds.size.y);
Debug.Log(r.bounds.size.z);
}
Needless to say this is just a quick solution, depending on the situation you might want to use this at runtime dynamically create content.
Yes, you can.
While placing the Image on the Image Marker to the relative size you want it to be, and when you run it you'll see that the size of the image will be relative to the Marker you've placed it on.

How to draw a GDI + text independent of DPI

I'm drawing a text using GDI+. I recently noticed that this text is automatically scaled when the DPI is changed. Is there a way to make the GDI+ text drawing independent of the DPI? E.g. I want to draw a text up to 20 pixels, regardless of the DPI. Is it possible? How to do this?
Below is a sample code. I want to draw the first text with a constant size, regardless of the DPI, and the second text normally:
case WM_PAINT:
{
inherited::WndProc(message);
Canvas->Brush->Style = bsSolid;
Canvas->Brush->Color = clWhite;
Canvas->FillRect(ClientRect);
// get GDI+ graphics from canvas
Gdiplus::Graphics graphics(Canvas->Handle);
// set text rendering hint
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintSystemDefault);
std::auto_ptr<Gdiplus::Font> pFont(new Gdiplus::Font(Canvas->Handle, Font->Handle));
std::auto_ptr<Gdiplus::SolidBrush> pBrush(new Gdiplus::SolidBrush(Gdiplus::Color(255, 0, 0, 0)));
std::auto_ptr<Gdiplus::StringFormat> pFormat(new Gdiplus::StringFormat());
Gdiplus::FontFamily fontFamily;
pFont->GetFamily(&fontFamily);
std::auto_ptr<Gdiplus::Font> pFont2(new Gdiplus::Font(&fontFamily, pFont->GetSize(),
pFont->GetStyle(), Gdiplus::UnitPixel));
Gdiplus::Unit test = pFont->GetUnit();
Gdiplus::Unit test2 = pFont2->GetUnit();
pFormat->SetAlignment(Gdiplus::StringAlignmentNear);
pFormat->SetLineAlignment(Gdiplus::StringAlignmentNear);
Gdiplus::StringFormatFlags flags = Gdiplus::StringFormatFlagsBypassGDI;
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionRightToLeft);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionVertical);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoWrap);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoClip);
pFormat->SetFormatFlags(flags);
pFormat->SetTrimming(Gdiplus::StringTrimmingEllipsisCharacter);
pFormat->SetHotkeyPrefix(Gdiplus::HotkeyPrefixNone);
std::wstring text = L"This is a sample code";
Gdiplus::Unit prevPageUnit = graphics.GetPageUnit();
try
{
graphics.SetPageUnit(Gdiplus::UnitPixel);
// draw text
graphics.DrawString(text.c_str(), text.length(), pFont2.get(), Gdiplus::RectF(ClientRect.Left,
ClientRect.Top, ClientWidth, ClientHeight), pFormat.get(), pBrush.get());
}
__finally
{
graphics.SetPageUnit(prevPageUnit);
}
// draw text 2
graphics.DrawString(text.c_str(), text.length(), pFont.get(), Gdiplus::RectF(ClientRect.Left,
ClientRect.Top + 25, ClientWidth, ClientHeight), pFormat.get(), pBrush.get());
return;
}
Regards
I wanted to mention something, slightly unrelated to your question. You shouldn't be using Graphics.DrawString in GDI+ anymore. It was deprecated in .NET 2. Instead Microsoft created TextRenderer.DrawString.
There are two ways of drawing text in .NET:
GDI+ (graphics.MeasureString and graphics.DrawString)
GDI (TextRenderer.MeasureText and TextRenderer.DrawText)
In .NET 1.1 everything used GDI+ for text rendering. But there were some problems:
There are some performance issues caused by the somewhat stateless nature of GDI+, where device contexts would be set and then the original restored after each call.
The shaping engines for international text have been updated many times for Windows/Uniscribe and for Avalon (Windows Presentation Foundation), but have not been updated for GDI+, which causes international rendering support for new languages to not have the same level of quality.
So they knew they wanted to change the .NET framework to stop using GDI+'s text rendering system, and use GDI. At first they hoped they could simply change:
graphics.DrawString
to call the old DrawText API instead of GDI+. But they couldn't make the text-wrapping and spacing match exactly as what GDI+ did. So they were forced to keep graphics.DrawString to call GDI+ (compatiblity reasons; people who were calling graphics.DrawString would suddenly find that their text didn't wrap the way it used to).
A new static TextRenderer class was created to wrap GDI text rendering. It has two methods:
TextRenderer.MeasureText
TextRenderer.DrawText
Note:
- TextRenderer is a wrapper around GDI
- graphics.DrawString is still a wrapper around GDI+
Then there was the issue of what to do with all the existing .NET controls, e.g.:
Label
Button
TextBox
They wanted to switch them over to use TextRenderer (i.e. GDI), but they had to be careful. There might be people who depended on their controls drawing like they did in .NET 1.1. And so was born "compatible text rendering".
By default controls in application behave like they did in .NET 1.1 (they are "compatible").
You turn off compatibility mode by calling:
Application.SetCompatibleTextRenderingDefault(false);
This makes your application better, faster, with better international support. To sum up:
SetCompatibleTextRenderingDefault(true) SetCompatibleTextRenderingDefault(false)
======================================= ========================================
default opt-in
bad good
the one we don't want to use the one we want to use
uses GDI+ for text rendering uses GDI for text rendering
graphics.MeasureString TextRenderer.MeasureText
graphics.DrawString TextRenderer.DrawText
Behaves same as 1.1 Behaves *similar* to 1.1
Looks better
Localizes better
Faster
It's also useful to note the mapping between GDI+ TextRenderingHint and the corresponding LOGFONT Quality used for GDI font drawing:
TextRenderingHint mapped by TextRenderer to LOGFONT quality
======================== =========================================================
ClearTypeGridFit CLEARTYPE_QUALITY (5) (Windows XP: CLEARTYPE_NATURAL (6))
AntiAliasGridFit ANTIALIASED_QUALITY (4)
AntiAlias ANTIALIASED_QUALITY (4)
SingleBitPerPixelGridFit PROOF_QUALITY (2)
SingleBitPerPixel DRAFT_QUALITY (1)
else (e.g.SystemDefault) DEFAULT_QUALITY (0)
Samples
Here's some comparisons of GDI+ (graphics.DrawString) verses GDI (TextRenderer.DrawText) text rendering:
GDI+: TextRenderingHintClearTypeGridFit, GDI: CLEARTYPE_QUALITY:
GDI+: TextRenderingHintAntiAlias, GDI: ANTIALIASED_QUALITY:
GDI+: TextRenderingHintAntiAliasGridFit, GDI: not supported, uses ANTIALIASED_QUALITY:
GDI+: TextRenderingHintSingleBitPerPixelGridFit, GDI: PROOF_QUALITY:
GDI+: TextRenderingHintSingleBitPerPixel, GDI: DRAFT_QUALITY:
i find it odd that DRAFT_QUALITY is identical to PROOF_QUALITY, which is identical to CLEARTYPE_QUALITY.
See also
UseCompatibleTextRendering - Compatible with whaaaaaat?
Sorting it all out: A quick look at Whidbey's TextRenderer
MSDN: LOGFONT Structure
AppCompat Guy: GDI vs. GDI+ Text Rendering Performance
GDI+ Text, Resolution Independence, and Rendering Methods.
Or - Why does my text look different in GDI+ and in GDI?
This is what works for me.
using namespace Gdiplus;
HDC hDC = ::GetDC( NULL );
int nDPI = ::GetDeviceCaps( hDC, LOGPIXELSY );
::ReleaseDC( NULL, hDC );
REAL fFontHeight = 96 / (REAL)nDPI * 8;
FontFamily fontFamily( L"Arial" );
Gdiplus::Font font( &fontFamily, fFontHeight, UnitPixel );
REAL fMeasuredFontHeight = font.GetHeight( &gr );
It turns out that Gdiplus::Font, despite being specified in pixels, uses the user's DPI setting to adjust the resulting font (even when the font is to be used to draw in a bitmap!). The standard DPI of 96 is a good value to use determine the correct ratio to adjust the font size.
In the above snippet, the font height sought was 8 pixels high.
fMeasuredFontHeight remains nearly constant (at approx. 12), through all DPI settings.

Render bitmap to SpriteBatch in DirectXTK

I need to port some C++ application to Windows Phone 8 (it is already on Android, iOS, WinCE and Win32). Currently I need to solving how to display graphic. I can get rendered bitmap from core application and I after succesfully initialize DirectXTK I'm able to render some DDS texture (DirectXTK::SpriteBatch). Now I need to transform my bitmap to texture and then render it. Can you help me with this out? Or is there some way to put bitmap directly to backbuffer and show it on display without SpriteBatch?
Thank you very much
Tomas
DirectX toolkit has WICTextureLoader. You can use it instead of DDSTextureLoader for loading .bmp(bitmap) file. Hope this help!
http://directxtk.codeplex.com/wikipage?title=WICTextureLoader&referringTitle=DirectXTK
Since WICTextureLoader is not supported on Windows Phone 8 the only way to render a bitmap to a texture is by mapping the texture to the CPU and copy your bitmap resource onto the mapped texture's resource.
ID3D11DeviceContext::Map()
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476457(v=vs.85).aspx
D3D11_MAPPED_SUBRESOURCE mappedBuffer;
HRESULT hr = pContext->Map(pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedBuffer);
if(hr == S_OK)
{
// copy your bitmap onto mappedBuffer.pData
...
pContext->Unmap(pTex, 0);
}

Resources