How can i extend this recolor function? - vb.net

I create a recolor function to recolor my picture box,
my function works red, it turn everything to red.
But now i want to input some Scroll Bar function to control it.
if i want 3 scroll bars which represent R , G , B
how can i do that base on my current function?
Try
' Retrieve the image.
image1 = New Bitmap("C:\Users\Anons\Desktop\Winter.jpg", True)
Dim x, y As Integer
' Loop through the images pixels to reset color.
For x = 0 To image1.Width - 1
For y = 0 To image1.Height - 1
Dim pixelColor As Color = image1.GetPixel(x, y)
Dim newColor As Color = _
Color.FromArgb(pixelColor.R, 0, 0)
image1.SetPixel(x, y, newColor)
Next
Next
' Set the PictureBox to display the image.
PictureBox1.Image = image1
' Display the pixel format in Label1.
Label1.Text = "Pixel format: " + image1.PixelFormat.ToString()
Catch ex As ArgumentException
MessageBox.Show("There was an error." _
& "Check the path to the image file.")
End Try
End Sub$

You simply need to multiply all three color components (R, G, and B) by a fractional factor which is determined by the scroll bar. For instance, a factor of 1 would keep it the same color. A factor of .5 would make the color half as bright. A factor of 2 would make it twice as bright, etc.
Dim rFactor As Single = rScroll.Value / 100
Dim gFactor As Single = gScroll.Value / 100
Dim bFactor As Single = bScroll.Value / 100
Dim newColor As Color = Color.FromArgb(pixelColor.R * rFactor, pixelColor.R * gFactor, pixelColor.B * bFactor)

Related

How to get rid of white space between picture boxes in VB.NET?

For fun I'm trying to recreate the first level of one my favorite games, Fire Emblem 7. I got a picture of the map online. I've broken down the image into "squares" with each square assigned a picture box to display the image. This is because each square needs to have certain properties such as terrain values, units inside them, etc.
The actual image is quite small (240 x 160), so I want to be able to scale it to any user defined value. The size of each square should be 16c x 16c with a scaler of c (all map dimensions are divisible by 16). For some reason, when c > 1, white lines appear between the squares. I've check the code and it looks like the squares should be adjacent with no empty spaces regardless of c.
I have provided a piece of my code and links to the images of different values of c below. Thank you for you help.
'This Sub Creates The Map From Initial Image And Assigns Part Of Image to Each Square
Public Sub New(Name As String, Image As Image)
Dim cropRect As Rectangle
Dim cropImage As Bitmap
Me.Name = Name
Me.Image = Image
Height = Me.Image.Height / 16
Width = Me.Image.Width / 16
ReDim Squares(Height - 1, Width - 1)
For i = 0 To Height - 1
For j = 0 To Width - 1
cropRect = New Rectangle(16 * j, 16 * i, 16, 16)
cropImage = New Bitmap(16, 16)
Graphics.FromImage(cropImage).DrawImage(Me.Image, 0, 0, cropRect, GraphicsUnit.Pixel)
Squares(i, j) = New Square(cropImage)
Next
Next
End Sub
'This Sub Sizes Each Square With User Defined Scale Value
Public Sub Draw(Scale As Double)
For i = 0 To Height - 1
For j = 0 To Width - 1
With Squares(i, j).Box
.Size = New Size(16 * Scale, 16 * Scale)
.Location = New Point(16 * j * Scale, 16 * i * Scale)
.SizeMode = PictureBoxSizeMode.StretchImage
End With
Next
Next
End Sub

Strolling Image - VB.net to get the latest colour

Need some guidance, the image below is scrolling on a website, from right to left, the colors will change between red or green, which are 255 values of each. Im not sure how i would do about seeing what the latest colour is as it scrolls, the example below shows that the red is the latest, but a few seconds ago the green was. Is there a way to say what the latest colour was.
I'm taking a BMP image off a window every 2 seconds, just after a textbox that says red or green. I cant see any example code of something similar on here, nor google.
Any help would be greatly appreciated.
Pete
You can search the bitmap for the target colors and add them into a Dictionary(Of Color, Point), add or update the value of each color in the dictionary (the point) whenever you find the key color at a greater X position. Use the LockBits approach to traverse the bitmap's bytes for faster and better performance.
When you have the dictionary filled with the required data, sort the values by their X properties in descending order and return the key (the color) of the first.
Imports System.Linq
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
' TODO: Find a better name...
Private Function GetLastColor(bmp As Bitmap, ParamArray colors() As Color) As Color
If bmp Is Nothing Then Return Color.Empty
' To work with 24-bit and 32-bit images...
Dim bpp = Image.GetPixelFormatSize(bmp.PixelFormat) \ 8
Dim bmpData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly, bmp.PixelFormat)
Dim bmpBuff((Math.Abs(bmpData.Stride) * bmpData.Height) - 1) As Byte
Marshal.Copy(bmpData.Scan0, bmpBuff, 0, bmpBuff.Length)
bmp.UnlockBits(bmpData)
Dim c As Color
Dim i As Integer
Dim dict As New Dictionary(Of Color, Point)
For y = 0 To bmp.Height - 1
For x = 0 To bmp.Width - 1
i = y * bmpData.Stride + x * bpp
c = Color.FromArgb(bmpBuff(i + 2), bmpBuff(i + 1), bmpBuff(i))
' Or color.ToArgb() = c.ToArgb() ...
If colors.Any(Function(color) Color.op_Equality(color, c)) Then
Dim p = New Point(x, y)
If Not dict.ContainsKey(c) Then
dict.Add(c, p)
ElseIf x > dict(c).X Then
dict(c) = p
End If
End If
Next
Next
If dict.Count > 0 Then
Return dict.OrderByDescending(Function(x) x.Value.X).First().Key
Else
Return Color.Empty
End If
End Function
Usage:
Sub Caller()
Dim c As Color = GetLastColor(
SomeBmp,
Color.FromArgb(255, 0, 0),
Color.FromArgb(0, 255, 0),
Color.FromArgb(0, 0, 255))
' TODO: ...
End Sub
Here's a demo creates an image every two seconds and fills small rectangles with random colors at random positions. The last rectangle is the one with a circle.

Creating a repeating line through looping by giving the x and y coordinates

I am experimenting on the paint event of VB.Net, and for this experiment I would like to create a repeating horizontal or vertical (depending on the parameter that I inputted) line and loop through until it meets the corresponding end point x and y.
Something like this:
What I'm trying to achieve is given the x and y start point and x and y end point the function should create either vertical or horizontal line that starts with the given start point until it reaches the given end point.
I can create curveline and straightline using the paintevent, but right now I don't have any idea on how to perform looping in the given x and y start point and end point.
You just need to use a For loop to iterate the x/y coordinates. Here's an example:
Public Class Form1
Private Enum Orientation
Vertical
Horizontal
End Enum
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Dim orient As Orientation = Orientation.Vertical
Dim x As Integer = 100 'X Coord
Dim y As Integer = 100 'Y Coord
Dim count As Integer = 10 'Number of Lines to draw
Dim spacing As Integer = 5 'Spacing between lines in pixels
Dim length As Integer = 20 'Length of each line in pixels
Dim thickness As Integer = 3 'Thickness of each line in pixels
drawLines(x, y, orient, count, spacing, length, thickness, e.Graphics)
End Sub
Private Sub drawLines(x As Integer, y As Integer, orient As Orientation, count As Integer, spacing As Integer, length As Integer, thickness As Integer, g As Graphics)
'Create the Pen in a using block so it will be disposed.
'The code uses a red pen, you can use whatever color you want
Using p As New Pen(Brushes.Red, CSng(thickness))
'Here we iterate either the x or y coordinate to draw each
'small segment.
For i As Integer = 0 To count - 1
If orient = Orientation.Horizontal Then
g.DrawLine(p, x + ((thickness + spacing) * i), y, x + ((thickness + spacing) * i), y + length)
Else
g.DrawLine(p, x, y + ((thickness + spacing) * i), x + length, y + ((thickness + spacing) * i))
End If
Next
End Using
End Sub
End Class
Have you tried something like:
For x = xstart to xend Step Spacing
Next
Where:
xstart = your start point
xend = your end point
Spacing = distance between lines

Custom colors on bar chart using Zedgraph library

Am using Zedgraph chart library but I can't seem to be able to color a bar graph depending on a specific condition. Am following along with the example found on this tutorial.
In my case, if the value isn't above 50 -which is the student.pass_mark variable-, I want to color the bar red and if its above 50 I want to color it green. Below is my code. Which so far only gives me red even though I have values of 100, 80, 110 etc.
Dim subject As String
Dim grade As Decimal
Dim colors As Color() = {}
Dim subject_names As String() = {}
For i = 0 To student.no_of_subjects
ReDim Preserve colors(i)
ReDim Preserve subject_names(i)
subject = student.subject_name
grade = student.grade
Dim x As Double = CDbl(i) + 1
Dim y As Double = grade
Dim z As Double = 0
list.Add(x, y, z)
If grade < student.pass_mark Then
colors(i) = Color.Red
Else
colors(i) = Color.Green
End If
subject_names(i) = subject
Next
Dim myCurve As BarItem = myPane.AddBar("Student Subject", list, Color.Blue)
'Dim colors As Color() = {Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Purple}
myCurve.Bar.Fill = New Fill(colors)
myCurve.Bar.Fill.Type = FillType.Solid
myCurve.Bar.Fill.RangeMin = 0
myCurve.Bar.Fill.RangeMax = 4
myPane.Chart.Fill = New Fill(Color.White, Color.FromArgb(220, 220, 255), 45)
myPane.Fill = New Fill(Color.White, Color.FromArgb(255, 255, 225), 45)
' Tell ZedGraph to calculate the axis ranges
' Set the XAxis labels
myPane.XAxis.Scale.TextLabels = subject_names
' Set the XAxis to Text type
myPane.XAxis.Type = ZedGraph.AxisType.Text
ZedChart.IsShowPointValues = True
ZedChart.AxisChange()
ZedChart.Refresh()
Also, I want to draw a line across the whole chart that shows the pass_mark so that it is quickly visible that a student' has or hasn't passed a certain subject in comparison to the passmark
I don't know whether it is still relative but you can do multi-colored bar plots in ZedGraph.
You can find the tutorial here:
http://zedgraph.dariowiz.com/indexb806.html?title=Multi-Colored_Bar_Demo
In your case you can use FillType.GradientByColorValue I assume.
For the line you can simply add a LineObj to the myPane.GraphObjList

vb.net Image Manipulation

I was tasked today after creating a program to Add watermarks to also create one to remove that same watermark.
My thoughts are that it is now part of the image and can't be removed so easily.
Is this accurate or is the actually a way? ( that doesnt take 10 years)
thanks for any hints
Here is my code to add the watermarks:
Dim watermark_bm As Bitmap = Global.AnchorAuditor.My.Resources.Logo_White
Dim watermark_bm2 As Bitmap = Global.AnchorAuditor.My.Resources.CLS_Logo_White_Engineering
'watermark_bm2.MakeTransparent()
' WATERMARK IMAGE 1 - AA
Using str As Stream = File.OpenRead(s)
Dim or_bm As Bitmap = Image.FromStream(str)
'''''''''''''''''''''''''START IMAGE 1''''''''''''''''''''''''''
or_bm.SetResolution(20, 20)
Dim x1 As Integer = or_bm.Width - 300
Dim Y As Integer = or_bm.Height - 300
Const ALPHA As Byte = 128
' Set the watermark's pixels' Alpha components.
Dim clr As Color
For py As Integer = 0 To watermark_bm.Height - 1
For px As Integer = 0 To watermark_bm.Width - 1
clr = watermark_bm.GetPixel(px, py)
watermark_bm.SetPixel(px, py, _
Color.FromArgb(ALPHA, clr.R, clr.G, clr.B))
Next px
Next py
' Set the watermark's transparent color.
watermark_bm.MakeTransparent(watermark_bm.GetPixel(0, _
0))
' Copy onto the result image.
Dim gr As Graphics = Graphics.FromImage(or_bm)
gr.DrawImage(watermark_bm, x1, Y)
'''''''''''''''''''''''''END IMAGE 1 START IMAGE 2''''''''''''''''''''''''''
or_bm.SetResolution(60, 60)
Dim x2 As Integer = 75
Dim Y1 As Integer = 75
Const ALPHA1 As Byte = 128
' Set the watermark's pixels' Alpha components.
Dim clr1 As Color
For py As Integer = 0 To watermark_bm2.Height - 1
For px As Integer = 0 To watermark_bm2.Width - 1
clr1 = watermark_bm2.GetPixel(px, py)
watermark_bm2.SetPixel(px, py, _
Color.FromArgb(ALPHA1, clr1.R, clr1.G, clr1.B))
Next px
Next py
' Set the watermark's transparent color.
watermark_bm2.MakeTransparent(watermark_bm2.GetPixel(0, _
0))
' Copy onto the result image.
Dim gr1 As Graphics = Graphics.FromImage(or_bm)
gr1.DrawImage(watermark_bm2, x2, Y1)
''''''''''''''''''''''''END IMAGE 2'''''''''''''''''''''''''''
or_bm.Save(s & "deleteme.jpg", _
System.Drawing.Imaging.ImageFormat.Jpeg)
End Using
You're correct - adding a watermark is far easier than removing it. The standard approach is to keep a copy of the original someplace and use that instead of trying to manipulate the image afterwards.