Sunday, July 28, 2013

Lossless image resize in C# by keeping same aspect ratio.

Now I am developing an image sharing and Indian social network application (www.Alap.Me) where I need to resize image (JPG for my case). This is a very common situation to all coders and it helps us if we get some readymade method which can serve our purpose. I found basic code of this somewhere from Google and later I modified it as I need and finally developed this code.
This code can resize any image by keeping aspect ratio, so your image always will be same in width vs. height ratio.

How to use it?


This is very easy to use this code; just you need to call it with image file name with full path and maximum height and width. My code automatically detects height or width, which is maximum at your parameter and based on this, code will set another parameter based on aspect ratio and finally resize your image.

ResizeImage(fileLocationWithName, maxWidth, maxHeight);

Complete Code in C#.Net


   public Bitmap ResizeImage(string fileNameWithPath, int maxWidth, int maxHeight)
    {        
        FileStream stream = new FileStream(fileNameWithPath, FileMode.Open);
        Stream streamImage = (Stream)stream;
        Bitmap originalImage = new Bitmap(streamImage);
        int newWidth = originalImage.Width;
        int newHeight = originalImage.Height;
        double aspectRatio = (double)originalImage.Width / (double)originalImage.Height;
         if (aspectRatio > 1 && originalImage.Width > maxWidth)
        {            
            newWidth = maxWidth;            newHeight = (int)Math.Round(newWidth / aspectRatio);
        }        
        else 
            if (aspectRatio <= 1 && originalImage.Height > maxHeight)
            {            
                newHeight = maxHeight;            newWidth = (int)Math.Round(newHeight * aspectRatio);
            }         
        Bitmap newImage = new Bitmap(originalImage, newWidth, newHeight);
        Graphics g = Graphics.FromImage(newImage);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;

        g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);         

        originalImage.Dispose();        
        stream.Close();        
        stream.Dispose();        
        return newImage;
    }


Complete code in VB.Net:

Public Function ResizeImage(fileNameWithPath As String, maxWidth As Integer, maxHeight As Integer) As Bitmap
 Dim stream As New FileStream(fileNameWithPath, FileMode.Open)
 Dim streamImage As Stream = DirectCast(stream, Stream)
 Dim originalImage As New Bitmap(streamImage)
 Dim newWidth As Integer = originalImage.Width
 Dim newHeight As Integer = originalImage.Height
 Dim aspectRatio As Double = CDbl(originalImage.Width) / CDbl(originalImage.Height)

 If aspectRatio > 1 AndAlso originalImage.Width > maxWidth Then
  newWidth = maxWidth
  newHeight = CInt(Math.Round(newWidth / aspectRatio))
 ElseIf aspectRatio <= 1 AndAlso originalImage.Height > maxHeight Then
  newHeight = maxHeight
  newWidth = CInt(Math.Round(newHeight * aspectRatio))
 End If

 Dim newImage As New Bitmap(originalImage, newWidth, newHeight)

 Dim g As Graphics = Graphics.FromImage(newImage)
 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear
 g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height)

 originalImage.Dispose()
 stream.Close()
 stream.Dispose()

 Return newImage
End Function

I have compressed attached picture by using my code and see here difference.
This is after re-size (around 30KB)



This is original size photo (around 5MB)

























I hope this will help you to make easier your coding. Thank you for reading my blog.

Wednesday, July 17, 2013

Small File Transfer Client to Client (via Server) using C#.Net socket programming



After long days I am writing this article and this is the complete package of these all articles about file transfer from one computer to another. Till now I have shown how to transfer file from client to server or server to client. But now I am merging these two things and creating one single application which can send data/file from one client to another client. It seems data is going directly from one client to another but actually it’s rotating via Server, I will explain here these things.

I am planning to stop this article series on Socket Programming in Desktop using C#.Net here for now and ignoring large file transfer sample from client to client because now a day is era of Web Programming. Long ago I tried to write code in web application with socket but I failed because web and desktop is totally different type of architecture. 

But in HTML5 is very powerful and it has introduced new thing to develop socket programming on web as well. In HTML5 there has Web Socket and using Web Socket Micorsoft has created SignalR which will be my next attraction of discussion. I shall try to explain and shall create multiple applications including Web Chat, message broadcasting system using these technologies. 

Before going to discuss Client to Client application I would like to recap earlier two post:


I am trying to explain how these were working.

   File Transfer from Client to Server

Server
Client
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.








5. Server receive client request and accept it. Once connection established, server create another socket object which will handle this client all requests until connection ends. Client will be informed internally by TCP about connect success.

6. Start preparations to store incoming byte data from client.



8. Server receives file byte data along with file name and stores it in byte array.

9. Server retrieve file name from byte data.

10. Server opens a binary stream writer with file name to store byte data in it. 

11. Once file save complete server closes binary stream writer and server socket objects.



14 Server program ends here.



2. Client creates an IP End Point and a socket object. 

3. Prepare byte data from file which will be sent to server.

4. Try to connect to server using client socket by help of IP end point.









7. Client starts sending byte data over connected socket.











12. Once data transfer complete and server closes socket connection, client also close client socket object.

13. Client program work ends here.



File Transfer from Client to Server
Server
Client
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.





4. Server receive client request and accept it. Once connection established, server create another socket object which will handle this client all requests until connection ends. Client will be informed internally by TCP about connect success.




6. Prepare byte data from file which will be sent to client.

7. Server starts sending byte data over connected socket.











12. Once data transfer complete and client closes socket connection, server also close server socket object.

13. Server program work ends here.



2. Client creates an IP End Point and a socket object.

3. Try to connect to server using client socket by help of IP end point.







5. Start preparations to store incoming byte data from server.






8. Client receives file byte data along with file name and stores it in byte array.

9. Client retrieve file name from byte data.

10. Client opens a binary stream writer with file name to store byte data in it.

11. Once file save complete client closes binary stream writer and server socket objects.






14. Client program work ends here.

So from these two tables it’s clear that in (1) Client to Server data transfer and (2) Server to Client program server and client is doing just like opposite execution.
 


When we transfer file over internet one client cannot connect to another directly because maximum client do not use static/global IP, so they cannot reach over other internet location directly. So to transfer file from client to client need server help. Server stays internet with a static IP which is accessible globally.  We will use server as temporary storage and to connect other client via server. Overall architecture will be as below:



In above picture, Client A is trying to send file to client B and both are taking help of Server in between to make connection. Client A and B both are inaccessible from outside internet because these are may be in DHCP inside a LAN or its IP has generated by some other local router. So both will connect to server and transfer data.
Now follow below communication chart to understand how data will be transferred. This chart is combination of first two chart. 


      Data Transfer      -- > -------------->-----------------------> -------------->----------------------->
Client A
Server
Client B





2. Client-A create IP End Point and a socket object.



4. Client A Prepare byte data from file which will be sent to server.

5. Client A tries to connect server using client socket by help of IP end point.





















8. Connection established with client A and server.







11. Client A starts sending byte data over connected socket.





































20. Client A receive file transfer success message from server.







22. Socket object closes and dispose.





24. Client A process ends here.
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.

















7. Server receives two client requests and accept these. Once connection established, server create new socket object for each connection (here total two, suppose sockObjectA for Client A and sockObjectB for Client B). These will handle client’s all requests until connection ends. Client will be informed internally by TCP about connect success. In our case sockObjectA will receive data and sockObjectB will send data.
For real life application can use socket object list (say array list or hash table) with some hash table to track client name and socket object name.






10. Start preparations to store incoming byte data from client A through sockObjectA.




12. Server receives file byte data along with file name and stores it in byte array. For large file can store in temporary file but I would suggest to store in array for faster processing. 

13. Server starts sending byte data over connected socket sockObjectB to client B.






















19. Server receive EOF successful message from client B and pass information to client A about file transfer success.





21. Server initiate to disconnect socket connection for sockObjectA and sockObjectB, so connection break with server and client A and B.
















26. Server process ends here for my case. For real life project server will stay in listen mode for next client request.








3. Client B creates IP End Point and a socket object.








6. Client B tries to connect server using client socket by help of IP end point.




















9. Connection established with client A and server.

















14. Client B receives file byte data along with file name and stores it in byte array.

15. Client retrieve file name from received byte data.

16. Client opens a binary stream writer with file name to store byte data in it.

17. Once file save complete client (do some technique to understand End Of File - EOF) closes binary stream writer and server socket objects.

18. Send a message to server to inform client A about file transfer success.


















23. Socket object closes and dispose.






25. Client B process here.
If you send large file then logic will be same and you need to loop step 11 to 20 until file ends. Here I have used EOF and then can use some fixed data packet every time. So once each packet receive in Client B, it will inform that successful receive of packet number and ask server to send next packet. 

For large file server will store file temporarily because connection speed in client A and B may not be same. Client A can send much faster data but client B may get it very slow. So buffering concept need to implement in server.

If possible I shall write this code in future.

Now I am posting this logic next will write code and once finish will post it for you with downloadable source code.