Drawing custom sprites onto a button in monogame - c#

I'm using monogame. I want to overlay Text onto one of my button images, but I want to use the image way of drawing;
spriteBatch.Draw(texture, destinationRectangle, sourceRectangle, Color.White);
so that I can control how the text is handled inside the bounds of the button image rectangle, like trim excess.
Is there a way to draw strings using the fontsprite, without using the spriteBatch.DrawString method, or is there more to this method that I haven't learned yet? It just seems limiting from its input parameters.

You can use Font.MeasureString to get the width and height of a string as a Vector2. You can subtract half of it from the center position of a Rectangle and you get your centered text.

Related

How can I make the picture smaller in the picture box without affecting the coordination?

I want to let the user define the area that they want to extract the text, but for the line item, the picture is too large and it make the rectangle cannot include the whole table.
I found a solution that able to smaller the picture but the coordinate also changed. For example, I draw the rectangle area at the "Malarvili" but the rectangle coordinate is not same as what I had drawn. Because of this, the extracted text is wrong.
So I want to know any solution to make the picture becomes smaller in the picturebox without affecting the original rectangle coordinate? Or using my original solution which is using the "autosize" without changing the picture size, but I have also facing a problem which is when i drawing the rectangle to the right, the scrollbar will not autoscroll and it makes me cannot draw the rectangle to the end of the right.
Any solution to solve these problems? Thanks a lot.
You can calculate the ratios (x and y axis) between the resize image (pictureBox with StretchImage mode) and the original image, and then calculate back the rectangle for original image from the rectangle you drawed in the pictureBox using these ratios.
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
ratio_X = (double) pictureBox.Width/original_image;
ratio_Y = (double) pictureBox.Height/original_image;
//suppose you have the rect drawed in the pictureBox: pictureBox_rect
//now make a rect for original_image
Rectangle original_rect = new Rect((int)pictureBox_rect.X * ratio_X,
(int)pictureBox_rect.Y * ratio_Y,
(int)pictureBox_rect.Width * ratio_X,
(int)pictureBox_rect.Height * ratio_Y)

Win2D draw single image

I'm able to fill a rectangle with an image and i apply a mask on top of the image using this code
args.DrawingSession.FillRectangle(rect, imgRnd, mask);
i need to apply some transform to this image, i'am able to do that with no issue, but i have encounter a strange issue, the last pixel is repeated.
i have used
imgRnd.ExtendX = CanvasEdgeBehavior.Wrap;
imgRnd.ExtendY = CanvasEdgeBehavior.Wrap;
and the image is repeated continuously.
My question is : there is a way to draw one time the image disabling and ExtendX and ExtendY?
FillRectangle will always fill all the pixels within the specified rectangle. The edge behavior enum controls what value they are filled with if the image is positioned such that it does not completely cover the rectangle being drawn.
How exactly are you transforming the image? Can you change that to also transform the rectangle itself, so you won't be trying to fill pixels that aren't covered by the image?
Another option is to use image effects (Microsoft.Graphics.Canvas.Effects namespace) which give much more detailed control than FillRectangle over how multiple images are transformed, combined, etc.

Set image offset of ImageBrush?

I've got a large image in memory which I convert to an System.Windows.Media.ImageBrush and use it as the Fill for a System.Windows.Shapes.Rectangle. You can move this rectangle around with your cursor.
Basically I want to use the rectangle as a "viewport". Thus I need to change which parts of the image get displayed within the rectangle, i.e., define a rectangular subsection of the image.
How can I do that?
I see ImageBrush.Viewport but that doesn't seem to mean the same thing.
I'm open to alternative solutions that don't involve a rectangle, such as drawing directly on a canvas or something, but AFAIK WPF doesn't let you access pixel data directly (at least not easily).
To achieve this your going to have to create your own rectangle user control to allow the user to create/resize a rectangle. Then I would create a CroppedBitmap of the image in the rectangle portion Cropped Bitmap MSDN Stackoverflow example
Edit
No, no, no #Mark, You dont turn the CroppedBitmap into a UserControl. You create a USerControl that exposed the CroppedBitmap. Basically, you create a UserControl with the following DependencyProperties
The Image
The Width of he cropped portion
The Height of the cropped portion
The Left of the cropped portion
Top of the cropped portion
Then as soon as any of these properties your DP callback will do a RenderTargetBitmap Crop of the new region.

c# Draw Image (Scaled) to Graphics, does not interpolate correctly. Fixes?

I have an image that is 1px wide, and some height. I need to draw this image across the entire width of the control on it's OnPaint event. I get it to draw, however not correctly. It seems like when it stretches it, it doesn't actually fill all the pixels. As if the interpolation is off. Is there a way to say "stop being smart, just draw it already"? I see no InterpolationMode.Off or .None in the options for the graphics object.
I can confirm I actually drawing the full width by using an image of width X where X is the same width as the control. Then when it draws, it covers the full area as normal. However this control is resized all the time, and to save memory and all that jazz using 1px wide images is quite normal in the web world. This is for a desktop C# application though. Any ideas on how to fix this?
Ok I figured out the magic keywords:
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
This coupled with setting the Interpolation Mode to NearestNeighbour allows for a full block to be drawn.
Without setting the Interpolation mode, you get weird blending (expected).
Without setting the PixelOffsetMode, the nearest neighbour algorithm has no neighbour to compare to on a blank paint and therefore only draws half the image, for half the width. Setting it to offset half, moves everything over by -0.5px, and allows this algorithm to work for block textures.
InterpolationMode.NearestNeighbor is what you want to use in this case.

How do I draw double height text using Graphics.DrawString?

I am trying to emulate a POS printer with System.Drawing and one of the functions I need is to draw text at double height. Any idea how I can do this using .Net's Graphics class?
Do I need to draw the text twice as large and condense it or draw normal size and then stretch? Both seem like messy options but is there an alternative?
Look at the transformation matrix on the Graphics object - you can control horizontal and vertical scaling independently.
Use a ScaleTransform and only scale up the y.

Categories