dizzy01
asked on
Image splicing
Hi,
I have written an application that takes two .tif images and splices the first on top of the second. It also reduces the spliced image's bit depth to 1. This application works but is REALLY slow :) and i was hoping for some help to improve it's performance. Any tips and/or code examples would be appreciated.
thanks.
Dom
I have written an application that takes two .tif images and splices the first on top of the second. It also reduces the spliced image's bit depth to 1. This application works but is REALLY slow :) and i was hoping for some help to improve it's performance. Any tips and/or code examples would be appreciated.
thanks.
Dom
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.data
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click
Dim tif1 As String = "c:\imgtest\004.tif"
Dim tif2 As String = "c:\imgtest\005.tif"
Dim tif3 As String = "c:\imgtest\006.tif"
Dim img1 As Image = Image.FromFile(tif1)
Dim img2 As Image = (Image.FromFile(tif2))
Dim Width As Integer = (img1.Width)
Dim Height As Integer = (img1.Height + img2.Height)
Dim img3 As Bitmap = (New Bitmap(Width, Height))
img3.SetResolution(200, 200)
Dim g As Graphics = (Graphics.FromImage(img3))
g.Clear(Color.Black)
g.DrawImage(img1, New Point(0, 0))
g.DrawImage(img2, New Point(0, img2.Height))
g.Dispose()
img1.Dispose()
img2.Dispose()
'new code from James
'lock the bits of the original bitmap
Dim bmdo As BitmapData = img3.LockBits(New Rectangle(0, 0, img3.Width, img3.Height), ImageLockMode.ReadOnly, img3.PixelFormat)
'add new 1bpp bitmap and lock its bits
Dim img4 As Bitmap = New Bitmap(img3.Width, img3.Height, PixelFormat.Format1bppIndexed)
img4.SetResolution(200, 200)
Dim bmdn As BitmapData = img4.LockBits(New Rectangle(0, 0, img4.Width, img4.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed)
'scan through the pixels y by x
Dim y As Integer
For y = 0 To img3.Height - 1
Dim x As Integer
For x = 0 To img3.Width - 1
'generate address of colour pixel
Dim index As Integer = y * bmdo.Stride + x * 4
'check it's brightness
If Color.FromArgb(Marshal.ReadByte(bmdo.Scan0, index + 2), Marshal.ReadByte(bmdo.Scan0, index + 1), Marshal.ReadByte(bmdo.Scan0, index)).GetBrightness() > 0.5F Then
Me.SetIndexedPixel(x, y, bmdn, True)
End If
Next
Next
'tidy up
img3.UnlockBits(bmdo)
img4.UnlockBits(bmdn)
img3.Dispose()
Dim info As ImageCodecInfo = Nothing
Dim ice As ImageCodecInfo
For Each ice In ImageCodecInfo.GetImageEncoders()
If ice.MimeType = "image/tiff" Then
info = ice
Exit For
End If
Next
Dim enc As Encoder = Encoder.SaveFlag
Dim ep As New EncoderParameters(1)
ep.Param(0) = New EncoderParameter(Encoder.Compression, CLng(EncoderValue.CompressionCCITT4))
img4.Save(tif3, info, ep)
img4.Dispose()
'end of new code
MsgBox("Done")
End Sub
Protected Sub SetIndexedPixel(ByVal x As Integer, ByVal y As Integer, ByVal bmd As BitmapData, ByVal pixel As Boolean)
Dim index As Integer = y * bmd.Stride + (x >> 3)
Dim p As Byte = Marshal.ReadByte(bmd.Scan0, index)
Dim mask As Byte = &H80 >> (x And &H7)
If pixel Then
p = p Or mask
Else
p = p And CByte(mask ^ &HFF)
End If
Marshal.WriteByte(bmd.Scan0, index, p)
End Sub
ASKER
Yes, that is the area that is taking the time. I couldn't think of a way to improve it but it's nice to know that i've not missed something. Thank you.
You may want to try the GetPixel method of a bitmap instead of using the Marshal.ReadByte.
Hi,
I think you can do image manipulation quicker in C# as you can make use of a native pointer to directly access the bytes instead of having to use multiple method calls. probably not the answer you were looking for.
if I were you I'd comment out the contents of your SetIndexedPixel method to see how much of an overhead this is adding initially. in essence there are lots of nested method calls which impact performance
I think you can do image manipulation quicker in C# as you can make use of a native pointer to directly access the bytes instead of having to use multiple method calls. probably not the answer you were looking for.
if I were you I'd comment out the contents of your SetIndexedPixel method to see how much of an overhead this is adding initially. in essence there are lots of nested method calls which impact performance
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
For y = 0 To img3.Height - 1
Dim x As Integer
For x = 0 To img3.Width - 1
'generate address of colour pixel
Dim index As Integer = y * bmdo.Stride + x * 4
'check it's brightness
If Color.FromArgb(Marshal.Rea
Me.SetIndexedPixel(x, y, bmdn, True)
End If
Next
Next
which would be taking a lot of time and i dont think there is any way of improving it.