Low quality image into a label - vb.net

I'm trying to pass an image showing to the user a countdown. For this, I'm using a separate thread where I'm checking when the countdown timer should be started, and when so, I draw an image for every 6 seconds passed.
What's annoying is when I pass the drawn image to the UI, the quality of the image is changed and it looks bad to the user.
This is my little script that handles the drawings:
Try
remainingTime = (#12:04:00 AM# - (DateTime.Now - local_DateTimeclick)).ToString("HH:mm:ss")
remainingTimeInSeconds = Convert.ToDateTime(remainingTime).Minute * 60 + Convert.ToDateTime(remainingTime).Second
If remainingTimeInSeconds Mod 6 = 0 Then
g.ResetTransform()
g.TranslateTransform(52, 52)
g.RotateTransform(230 - remainingTimeInSeconds / 6 * 9)
'g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
'g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
'g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
'g.CompositingMode = Drawing2D.CompositingMode.SourceCopy
'g.PixelOffsetMode = Drawing2D.PixelOffsetMode.
g.DrawImage(Tick, 10, 10)
End If
Catch
remainingTime = "Times Up"
End Try
In the above section,
- *local_DateTimeClick* is the variable that is set when the countdown should start
- Tick is a Bitmap that represents the image i have to draw for every 6 elipsed seconds
- g is a Graphics object from image that i return into the main window.
Also tried with changing the properties of g, but there was no positive effect.
Anyone have any idea what can i do to make this properly work without changing the quality of the returned image? Any tip/advice is welcomed.

Because Drawing2D.SmoothingMode only applies for 2D vector drawing methods such as Graphics.DrawEllipse and Graphics.DrawLine.
It doesn't affect drawing bitmaps with Graphics.DrawImage.
From the .NET documentation:
The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing).
You have two options at this point:
Pre-render every possible orientation of the image, and then just display different Image objects at each tick
use the .NET vector drawing methods to render your image instead of using a pre-rendered bitmap.
Without knowing the actual image you're transforming, I can't say which would be more appropriate.

from a graphic designer perspective followed at my company, i think your should crop your images to fit in the label:
1. it enhance performance by saving processing power.
2. it look better ?!.
regards

Related

How would one draw an arbitrary curve in createJS

I am attempting to write a function using createJS to draw an arbitrary function and I'm having some trouble. I come from a d3 background so I'm having trouble breaking out of the data-binding mentality.
Suppose I have 2 arrays xData = [-10, -9, ... 10] and yData = Gaussian(xData) which is psuedocode for mapping each element of xData to its value on the bell curve. How can I now draw yData as a function of xData?
Thanks
To graph an arbitrary function in CreateJS, you draw lines connecting all the data points you have. Because, well, that's what graphing is!
The easiest way to do this is a for loop going through each of your data points, and calling a lineTo() for each. Because the canvas drawing API starts a line where you last 'left off', you actually don't even need to specify the line start for each line, but you DO have to move the canvas 'pen' to the first point before you start drawing. Something like:
// first make our shape to draw into.
let graph = new createjs.Shape();
let g = graph.graphics
g.beginStroke("#000");
xStart = xData[0];
yStart = yourFunction(xData[0]);
g.moveTo(xStart, yStart);
for( let i = 1; i < xData.length; i++){
nextX = xData[i], but normalized to fit on your graph area;
nextY = yourFunction(xData[i]), but similarly normalized;
g.lineTo(nextX, nextY);
}
This should get a basic version of the function drawing! Note that the line will be pretty jagged if you don't have a lot of data points, and you'll have to treat (normalize) your data to make it fit onto your screen. For instance, if you start at -10 for X, that's off the screen to the left by 10 pixels - and if it only runs from -10 to +10, your entire graph will be squashed into only 20 pixels of width.
I have a codepen showing this approach to graphing here. It's mapped to hit every pixel on the viewport and calculate a Y value for it, though, rather than your case where you have input X values. And FYI, the code for graphing is all inside the 'run' function at the top - everything in the PerlinNoiseMachine class is all about data generation, so you can ignore it for the purposes of this question.
Hope that helps! If you have any specific follow-up questions or code samples, please amend your question.

Accessing pixel values from destination image of CopyMakeBorder function in Emgu CV

A little bit new to EmguCV here
Just want to ask quick question, about CopyMakeBorder function
Are the pixel values of the destination image accessible?
I want to process further the destination image, but when I tried to access pixel values from the image, it only returns me 0 (even in the location that are not supposed to be 0, for example the central pixel). When I used Imshow, it shows that the image borders are perfectly processed, but problem only persist when I try to access the pixel values, only getting 0 wherever the pixel location is.
This is not a problem when I tried to use destination images from other EmguCV functions, such as Threshold Function
Can anyone clarify? Thanks A lot!!
I am using VB.net, here is the code (I am away from my workstation for the weekend so I am just gonna try to remember the code, probably some capital letters here and there are mistyped, but I hope you get the gist.)
First I initialize the source images and destination image
Dim img As Image(Of Gray,Byte) = New Image (Of Gray, Byte)("myimage.jpg")
Dim img1 As Image(Of Gray,Byte) = New Image (Of Gray, Byte)(img.size)
CopyMakeBorder Function, extend 1 pixel to top, bottom, left and right. Border type constant 0 values
Cvinvoke.CopyMakeBorder(img,img1,1,1,1,1,BorderType.Constant, New MCvscalar(0))
Accessing pixel values from destination image, take example pixel in x = 100, y = 100, and channel 0 (as it is a grayscale image)
Console.writeline(img1.data(100,100,0))
This will make debug output to 0, and no matter where I try to take the pixel values, it is still 0, even though when I try to show the image that specific pixel should not be 0 (it is not black)
Cvinvoke.Imshow("test",img1)
You are trying to access the data through Image.Data, however, this doesn't include the added border(s); just the original bitmap.
The added border is in the Mat property, however. Through it the individual pixels can be accessed
' returns data from original bitmap
Console.WriteLine(img1.Data(100, 100, 0))
' returns data from modified bitmap
Console.WriteLine(img1.Mat.GetData(100, 100)(0))

Resize image and keep aspect ratio

I'm trying to make zoom in/out buttons, but for whatever reason I just can't figure out how to maintain the aspect ratio and resize the image by - say 90% or 110%
The issue is that I'm trying to make it so that when you click the zoom out button 4 times, then click the zoom in button 4 times, the image would be its original size. There's no defined width since I'm trying to make the new width be 90%/110% of the existing width, but obviously multiplying by 0.9 and 1.1 doesn't do that correctly.
I currently have the following code..
Dim source As New Bitmap(PictureBox1.Image)
Dim NewWidth As Integer = source.Width * 0.9
Dim NewHeight As Integer = NewWidth * (source.Height / source.Width)
Any help is appreciated. I'm sure I'm just over-thinking it again, but some guidance would be appreciated :)
The best approach is to begin each resize operation with a copy of the original image. Have your buttons represent the total zoom factor (so say add 0.1 zoom for the + and subtract 0.1 zoom for the -).
You want to start with the original image each time because otherwise successive operations will quickly distort the image due to the interpolation inherent in zooming in and out.

Comparing two images - Detect egg in a nest

I have a webcam directly over a chicken nest. This camera takes images and uploads them to a folder on a server. I'd like to detect if an egg has been laid from this image.
I'm thinking the best method would be to compare the contrast as the egg will be much more reflective than the straw nest. (The camera has Infrared so the image is partly grey scale)
I'd like to do this in .NET if possible.
Try to resize your image to a smaller size, maybe 10 x 10 pixel. This averages out any small disturbing details.
Const N As Integer = 10
Dim newImage As New Bitmap(N, N)
Dim fromCamera As Image = Nothing ' Get image from camera here
Using gr As Graphics = Graphics.FromImage(newImage)
gr.SmoothingMode = SmoothingMode.HighSpeed
gr.InterpolationMode = InterpolationMode.Bilinear
gr.PixelOffsetMode = PixelOffsetMode.HighSpeed
gr.DrawImage(fromCamera, New Rectangle(0, 0, N, N))
End Using
Note: you do not need a high quality, but you need a good averaging. Maybe you will have to test different quality settings.
Since now, a pixel covers a large area of your original image, a bright pixel is very likely part of an egg. It might also be a good idea to compare the brightness of the brightest pixel to the average image brightness, since that would reduce problems due to global illumination changes.
EDIT (in response to comment):
Your code is well structured and makes sense. Here some thoughts:
Calculate the gray value from the color value with:
Dim grayValue = c.R * 0.3 + c.G * 0.59 + c.B * 0.11
... instead of comparing the three color components separately. The different weights are due to the fact, that we perceive green stronger than red and red stronger than blue. Again, we do not want a beautiful thumbnail we want a good contrast. Therefore, you might want to do some experiments here as well. May be it is sufficient to use only the red component. Dependent on lighting conditions one color component might yield a better contrast than others. I would recommend, to make the gray conversion part of the thumbnail creation and to write the thumbnails to a file or to the screen. This would allow you to play with the different settings (size of the thumbnail, resizing parameters, color to gray conversion, etc.) and to compare the (intermediate) results visually. Creating a bitmap (bmp) with the (end-)result is a very good idea.
The Using statement does the Dispose() for you. It does it even if an exception should occur before End Using (There is a hidden Try Finally involved).

Drawing an angle/angular/"Conical"/"Arcing" gradient in Objective-C (IOS) using Core Graphics

I'm trying to draw a "conical"/"arcing" gradient (I don't know what would be the correct term for this) (Photoshop calls it an "angle" gradient —your friendly neighborhood stackoverflow editor) using Objective-C (IOS), pretty much exactly like the image shown in the following thread.
After days of googling and searching the internet to no avail, I've decided to ask for help here.
A little background on what I'm trying to do. My objective is to create a custom UIView, which is circular progress bar, a ring basicly, somewhat similar to the activity indicator as seen in the TweetBot iPhone app (displays when you drag to refresh, which can be seen in action here, around 17-18 seconds into the video, on top of the iphone screen). I want the progress indicator (the fill of the ring) to be a simple two color gradient, which can be set programmatically, and the view to be resizable.
Filling the ring shape with a gradient that "follows" the arc of the ring is where I'm stuck. The answers that I get from googling, reading Apple's Core Graphics documentation on gradients and searching on SO are either about radial gradients or linear/axial gradients, which is not what I'm trying to achieve.
The thread linked above suggests using pre-made images, but this isn't an option because the colors of the gradient should be settable, the view should be resizable and the fill of the progress bar isn't always 100% full obviously (which would be the state of the gradient as shown in the picture in the thread above).
The only solution that I've come up with is to draw the gradient "manually", so without using a CGGradientRef, clipping small slices of the gradient with single solid color fills within a circular path. I don't know exactly how well this will perform when the bar is being animated though, it shouldn't be that bad, but it might be a problem.
So my first question:
Is there an easier/different solution to draw a conical/arcing gradient in Objective-C (IOS) than the solution I've come up with?
Second question:
If I have to draw the gradient manually in my view using the solution I came up with, how can I determine or calculate (if this is even possible) the value (HEX or RGBA) of each color "slice" of the gradient that I'm trying to draw, as illustrated in the image below.
(Can't link image) gradient slice illustration
Looks to me like a job for a pixel shader. I remember seeing a Quartz Composer example that simulated a radar sweep, and that used a pixel shader to produce an effect like you're describing.
Edit:
Found it. This shader was written by Peter Graffignino:
kernel vec4 radarSweep(sampler image, __color color1,__color color2, float angle, vec4 rect)
{
vec4 val = sample(image, samplerCoord(image));
vec2 locCart = destCoord();
float theta, r, frac, angleDist;
locCart.x = (locCart.x - rect.z/2.0) / (rect.z/2.0);
locCart.y = (locCart.y - rect.w/2.0) / (rect.w/2.0);
// locCart is now normalized
theta = degrees(atan(locCart.y, locCart.x));
theta = (theta < 0.0) ? theta + 360.0 : theta;
r = length(locCart);
angleDist = theta - angle;
angleDist = (angleDist < 0.0) ? angleDist + 360.0 : angleDist;
frac = 1.0 - angleDist/360.0;
// sum up 3 decaying phosphors with different time constants
val = val*exp2(-frac/.005) + (val+.1)*exp2(-frac/.25)*color1 + val*exp2(-frac/.021)*color2;
val = r > 1.0 ? vec4(0.0, 0.0,0.0,0.0) : val; // constrain to circle
return val;
}
The thread linked above suggests using pre-made images, but this isn't an option because the colors of the gradient should be settable, the view should be resizable and the fill of the progress bar isn't always 100% full obviously (which would be the state of the gradient as shown in the picture in the thread above).
Not a problem!
Use the very black-to-white image from the other question (or a bigger version if you need one), in the following fashion:
Clip to whatever shape you want to draw the gradient in.
Fill with the color at the end of the gradient.
Use the black-to-white gradient image as a mask.
Fill with the color at the start of the gradient.
You can rotate the gradient by rotating the mask image.
This only supports the simplest case of a gradient with a color at each extreme end; it doesn't scale to three or more colors and doesn't support unusual gradient stop positioning.
FYI: here's also a good tutorial for creating a circular progress bar using Quartz drawing.
http://www.turnedondigital.com/blog/quartz-tutorial-how-to-draw-in-quartz/