I am trying to use GetPixel and SetPixel to copy the contents of one picture to another (I know there are other methods to do so, but there are reasons I want to try this ;D)
Anyway, the pictures are .png images, so they include transparency settings.
But for some reason, it seems like when I use GetPixel & SetPixel to put one image over another, it seems the second image completely replaces the other one. I mean, it seems the transparency settings are not respected when I use GetPixel & SetPixel.
Both images have the same size. Both have transparent areas.
Before calling SetPixel() you need to call MakeTransparnet(). Here's some code that copies the contents of the first pixel in an alpha-image onto another image and retain's the first image's alpha channel:
Using img1 = New Bitmap("c:\Users\Owner\Desktop\1.png")
PX = img1.GetPixel(0, 0)
End Using
Using img2 = New Bitmap("c:\Users\Owner\Desktop\2.png")
img2.MakeTransparent() '//Sets the transparent value and converts the image to Format32bppArgb
img2.SetPixel(0, 0, PX)
img2.Save("c:\Users\Owner\Desktop\3.png")
End Using
Related
I am making an application in vb.net that has a good user interface, including the your account icon that includes a picture box. My question is that how can i make that image in the picture box round in shape?
Like This:
https://drive.google.com/open?id=1rUBq68ULDkTiFFv2uEiV_oQIh3wQIfhd
I wouldn't normally provide code for a question that doesn't show an attempt but there are a few steps in the answer and it was easier to just write the code myself than explain them. E.g.
'Get the original image.
Dim originalImage = PictureBox1.Image
'Create a new, blank image with the same dimensions.
Dim croppedImage As New Bitmap(originalImage.Width, originalImage.Height)
'Prepare to draw on the new image.
Using g = Graphics.FromImage(croppedImage)
Dim path As New GraphicsPath
'Create an ellipse that fills the image in both directions.
path.AddEllipse(0, 0, croppedImage.Width, croppedImage.Height)
Dim reg As New Region(path)
'Draw only within the specified ellipse.
g.Clip = reg
g.DrawImage(originalImage, Point.Empty)
End Using
'Display the new image.
PictureBox2.Image = croppedImage
That will create an elliptical image with the same width and height as the original. If the original is square then the final will be circular. If you want a circle regardless of the aspect ratio of the original then you'll have to manipulate that in the appropriate manner.
Though i see that you already found out the solution to your question, however here's a very simple workaround.
Assuming, your project is in WinForms, and you are using Picture Box control. The easiest way to achieve the round-image-look is to set the Image property of the PictureBox to an image that is round-shaped and is blank/transparent in the middle and white on the outside. Then , whatever image you set as a BackgroundImage , it will appear round-ish.
Here's a sample round-transparent image for you which you can set as Image(make sure to set SizeMode to stretch) and then set any picture as BackgroundImage.
I am trying to implement a 'Flag' w/ a menustrip.
I have an image list w/ a red flag and a black flag.
When I click the menu item, i want to toggle the image.
The problem I have is that once I change the image, it wants to do SizeToFit which makes the Icon roughly the height of text. I dont want that. I want the Image to be its actual size.
I have tried putting the statements in different orders, nothing i have tried seems to work.
Currently, I have the button set to the black flag at design time.
This code shows me trying to change to a Red flag.
tsbFlagPatient.Image = ilFlags.Images(1)
tsbFlagPatient.ImageScaling = ToolStripItemImageScaling.None
tsbFlagPatient.DisplayStyle = ToolStripItemDisplayStyle.Image
[If there is some better way to approach toggling the image, im open to that. That seems like a separate question. ]
I was unable to make ImageScrolling work.
Since I dont need text here, I used BackGround Image and set
BackgroundImageLayout = Stretch
This allows the images to be the right size.
You can turn AutoSize = false and then manually set Height, Width to fine tune your menu's size.
I did reconsider the ImageList and changed the images to being stored in the project Resources. This is the code to toggle the image
Public Sub SetFlagImage(flagSet As Boolean)
If flagSet = False Then
btnFlag.BackgroundImage = My.Resources.appbar_flag_wavy_black
btnFlag.BackgroundImage.Tag = "black"
Else
btnFlag.BackgroundImage = My.Resources.appbar_flag_wavy_red
btnFlag.BackgroundImage.Tag = "red"
End If
End Sub
This had no effect on the question posed here. In general, probably better than having an image list because all forms can access it.
During the use of the application the user stores away a picture to be used for comparison later.
When the image is retrieved from the database it does not render fully in the picture box as seen below. The correct image has been retrieved but only the top is visible.
I have tried multiple different picture box settings and image types but the result is always the same. I have also reproduced the error in another project with the same code.
The code I use is below:
Dim b() As Byte
b = DirectCast(cmd.ExecuteScalar, Byte())
If b Is Not Nothing Then
stream = New System.IO.MemoryStream
stream.Write(b, 0, b.Length)
Dim image As Image = image.FromStream(stream)
pictureBox.Image = image
End if
I cannot figure this out. Has anyone seen something like this before?
Thanks!
Where you define stream? If you read the Image.FromStream method documentation it say:
You must keep the stream open for the lifetime of the Image.
The stream is reset to zero if this method is called successively with
the same stream.
I've written some VBA code that automatically creates a chart. One of the axes on this chart doesn't use normal labels but a graphic. I've stored the graphic as an image and I use the .Copy and .Paste methods to get a copy of this image onto the chart.
Here is where it gets confusing. I need to rotate the image to get it aligned with the axis (using the .rotation property). But when I set the .top and .left properties the shape doesn't end up where I would expect. In fact setting the properties to 0 and 0 doesn't do what I would expect either. I've tried changing the order of the way I set the properties on the image object but it only appears in a different (wrong) location.
I'm sure I'm missing some vital aspect of how VBA/Excel is placing the object relative to what I'm setting the top and left properties to. Basically my goal is to make the image on the left side of the chart with the same width as the plot area's height (since the image is rotated I theorize this will make it the same size).
This code does not work:
Sheets(ImageSheet).Shapes("agreement").Copy
c.Chart.Paste
c.Chart.Shapes(1).Rotation=270
c.Chart.Shapes(1).width = c.Chart.PlotArea.height
c.Chart.shapes(1).left = 5
c.Chart.Shapes(1).top = c.Chart.PlotArea.top
I've also tried this code
c.chart.Shapes(1).top = c.chart.PlotArea.top + c.Chart.PlotArea.height
because I thought maybe it was calculating the "top" as the upper-left corner of the image object when it is not rotated (rotating 270 degrees makes this point in a place where it should align with the bottom of the plot area). But that doesn't do what I expected either.
The image is a skinny rectangle that acts as a label for the axis. The chart will end up being laid out like this: http://imgur.com/NrSXR and the axis label image would be something like this http://imgur.com/08EWU
What am I missing here?
Is it possible for you to align your chart into a position where the shape could rest align/on a cell?
IF YES then here is a suggestion:-
You could position shape into a cell. Then adjust the size to what you need. And rotate.
Then change its bring forward property be shown on the Chart.
Next Group Chart and the Shape
PS: I recorded a macro. However it's best if you could show us what your the exact picture (=how your sheeet/chart/image should look like) of your question.
I ended up rotating and resizing the image before copying and pasting to the chart and then positioning it. I had to use the IncrementLeft and IncrementTop methods rather than setting the left and top properties directly because that did not have the desired effect.
When doing the paste into the chart the object always ended up in the upper left hand-corner so I could increment to the left by the small amount I wanted as a margin I wanted there and increment the top by the value of PlotArea.top to align it with the plot area.
I was also surprised that when creating the copy of my image it retained the "name" i referred to it as when I copied it to the new sheet and chart. This was especially useful for positioning the image once it was on the chart.
I also needed execute this code at the very end of my procedure, after everything else had been positioned and aligned, or when I positioned the data labels for one of my series they wouldn't appear correctly.
Here is the code that I ended up using:
'make a copy of the label image and refer to it with a variable for convenience
Sheets(ImageSheet).Shapes("maturity").Copy
i = Sheets(ImageSheet).Shapes.Count
Sheets(ImageSheet).Paste
Dim axisImage As Shape
Set axisImage = Sheets(ImageSheet).Shapes(i + 1)
'rotate and resize the image
With axisImage
.Rotation = 270
.width = c.Chart.PlotArea.height
End With
'cut and paste the new image to the chart
axisImage.Cut
c.Chart.Paste
'position it in the chart using IncrementTop and IncrementLeft because setting the properties directly does not have the desired effect
c.Chart.Shapes("maturity").IncrementTop c.Chart.PlotArea.top
c.Chart.Shapes("maturity").IncrementLeft c.Chart.PlotArea.left - c.Chart.Shapes("maturity").height
I'm attempting to write a solution so that my user's can "watermark" their Images with their Company Logo. I've got the actual watermarking part done and working so now I'm creating the "upload logo" feature so that they can provide me with the Logo they wish to appear watermarked onto their Images.
I'm using VB.NET and this will probably end up in a Web Service that accepts the Logo JPG file, and returns the "altered" Logo. What I need to happen in this Web Service is:
1) Gray-scale the image. Which I have working as well, thanks to this article.
2) Make the background transparent (so the logo looks clean when watermarked onto an image). This is where I'm stuck.
I think for the most part, any logos that are uploaded will have a generic white background but I can't assume that. Is there a way to somehow detect the background of an image or the background colors, so that I may make those colors transparent?
I've downloaded and ran this project from code.google.com, called Transpoint, which is pretty much what I need except I won't be able to have this as a stand-alone app. Also, I think this is written in Python which is foreign to me.
So basically what I need is just a way to determine the background on an Image (if that's even possible?) or even just the background colors so that I may make them transparent. Any help/advice/suggestions would be greatly appreciated!
Thanks,
Lloyd
You could do something like reading the upper-left pixel and assuming that that pixel is representative of the background color, and then iterating through the image and setting the alpha value of each matching pixel (matching by color) to 0.
I can pretty much guarantee you, however, that the result will be awful. For transparency to work properly and look good, the image needs to support partial transparency, such that some pixels are completely transparent whereas some are only partially transparent. Any algorithm that takes a non-transparent image and sets only one color in the image to fully transparent is going to end up with jagged edges.
Most companies I've ever dealt with have versions of their logos done by professional artists, with smooth, partial transparency. You'd be much better off just requiring customers to submit a logo with transparency than trying to make a non-transparent image into a transparent one with code. Sorry, but this just doesn't work.
I think this would actually work (sorry it's just a description):
Assuming the upper-left corner pixel is the image's background color, you could iterate through each pixel in the image and set the alpha to 0 if the pixel color matches the background color (either exactly or within some threshold color distance). This would then leave you with an image with a transparent background but jagged edges when you re-draw it on a different-color background. Also, if the background color is present anywhere inside the image itself, it will be turned transparent, which you don't want.
To fix the latter problem, your algorithm should start scanning each row of the image from left to right, and stop when it reaches a non-background color pixel; at this point it should start on the same row and scan right to left until reaching a non-bg pixel.
To fix the edges, you can just blur the alpha values of the bitmap. Basically, you re-calculate the alpha value of each pixel as the average of 9 pixels (itself and the 8 pixels surrounding it, and just the alpha values - not the rgb values). To prevent sequencing artifacts, you would have a temporary array to store the averaged pixel values, which you would then copy back into the image's alpha values at the end of the process.
Also, there's probably one or more third-party tools that do this (is LEAD Tools still around?).
#MusiGenesis (and anyone else who may be interested) here is what I did to (kind of) solve my problem. I basically followed the first half of your idea. I've created a function that will accept a bitmap, check each pixel against the first pixel at (0,0) - using a threshold of 10 for each RGB color. For each color within that threshold, the pixel is made transparent. Here is my code, which seems to work alright for the few images I've tried it with:
Private Function TransparifyBackground(ByVal bmp As Bitmap) As Bitmap
Dim temp As Color
Dim background As Color = bmp.GetPixel(0, 0) 'top left will be assumed background color
For y As Integer = 0 To bmp.Height - 1
For x As Integer = 0 To bmp.Width - 1
'get the pixel for this position:
temp = bmp.GetPixel(x, y)
If ColorsMatch(background, temp) Then
'Make the Alpha value 50 for each pixel, leaving the other colors
Dim newColor As New Color
newColor = Color.Transparent
bmp.SetPixel(x, y, newColor)
End If
Next
Next
Return bmp
End Function
Private Function ColorsMatch(ByVal background As Color, ByVal temp As Color) As Boolean
Dim nThreshold As Integer = 10
Dim temp_R As Integer = CInt(temp.R)
Dim temp_G As Integer = CInt(temp.G)
Dim temp_B As Integer = CInt(temp.B)
Dim R As Integer = CInt(background.R)
Dim G As Integer = CInt(background.G)
Dim B As Integer = CInt(background.B)
'check the difference of each value against our threshold:
If ((temp_R - R) < nThreshold) AndAlso ((temp_G - G) < nThreshold) AndAlso ((temp_B < B) < nThreshold) Then
Return True
Else
Return False
End If
End Function