Click here to Skip to main content
15,881,600 members
Articles / Web Development / ASP.NET

Facebook Style Photo Tag

Rate me:
Please Sign up or sign in to vote.
4.57/5 (19 votes)
20 Jun 2011CPOL3 min read 59.2K   3K   50   15
Facebook Style Photo Tag

Introduction

You know how in Facebook, you can Tag images like this:

fbTag.jpg

How can this be done in .NET ?

BreakDown

We'll have to divide this feature into a number of components:

  1. Select an area
  2. A list of friends is shown
  3. After selecting a friend, a label with friends name is added
  4. Friend name is removed from list (step 2)
  5. Image is now marked with the friends name where you selected
  6. On hovering the label with friend name, area from step(1) is selected

For steps (1) and (6), we will use Michal Wojciechowski's imgAreaSelect.

We'll get into that shortly, first let's examine the database.

ERD

ERD.jpg

vTags.jpg

tPhoto 

Nothing special here, holds the photo name, id and path.

tFriend

we need a boolean to tell us whether the friend has been tagged already or not, so he won't be shown again in the list (step number 2).

tTag

Holds the data about areas position in the photo, and Id of tagged person.

In real life the tables are more complex, where a friend can be tagged in more than one photo and a photo can have more than one friend tagged, this is simplified for the sake of demonstration.

vTag
The view displaying the tagged friends, the special field here is Coords, which is areas' positions(from tTag,x1,y1,x2,y2) concatenated together ,we'll need that later 

How to Use the Code

This is the JavaScript function imgAreaSelect(), notice it's bound to our asp:Image control, Image1, it magically frames the area we selected based on image name.

our image control name in run-time is MainContent_Image1 , that's the one we'll use. 

JavaScript
$(function () {
            $('#MainContent_Image1').imgAreaSelect({ aspectRatio: '1:1', handles: true,
                fadeSpeed: 200, onSelectChange: Select, onSelectEnd: DisplayFriends
            });
        });        

We have 4 hidden fields in the page, we need those to store the positions of area selected.

Now, this function fires the onSelectEnd event, which calls the function Select(), it simply populates the hidden fields.

JavaScript
function Select(img, selection) {
if (!selection.width || !selection.height)
return;
document.getElementById('<%=x1.ClientID %>').value = selection.x1;
document.getElementById('<%=y1.ClientID %>').value = selection.y1;
document.getElementById('<%=x2.ClientID %>').value = selection.x2;
document.getElementById('<%=y2.ClientID %>').value = selection.y2;
}  

... and on the onSelectEnd event, we'll call our DisplayFriends() method.

dvFriends is a div containing a datalist populated with our untagged friends (initially hidden of course).

JavaScript
function DisplayFriends(img, selection) {
if (!selection.width || !selection.height || 
	document.getElementById('<%=HFShowFriends.ClientID %>').value == "0")
return;
document.getElementById('<%=dvFriends.ClientID %>').style.display = "block";
}    

When user selects a friend, it will fire the function SelectEnd() which ends the selection process.

JavaScript
function SelectEnd() {
$('#MainContent_Image1').imgAreaSelect({ hide: true });
}  

Nice, now we need to actually tag the image (where you hover on photo and see a tool tip displaying the friend's name).

To do this, we'll use an HTML map.

AddNewArea() function takes the newly created tTag object and adds a new area to the map.

C#
private void AddNewArea(tTag t)
{
    HtmlGenericControl gcArea = new HtmlGenericControl("area");
    gcArea.Attributes.Add("shape", "rect");
    gcArea.Attributes.Add("href", "#");
    string strFriendName = Friends.GetFriendName(t.nFriendId);
    gcArea.Attributes.Add("id", "a" + t.nFriendId.ToString());
    gcArea.Attributes.Add("title", strFriendName);
    gcArea.Attributes.Add("alt", strFriendName);
    gcArea.Attributes.Add("coords", GenerateCoordiantes(t));
    mapPhoto.Controls.Add(gcArea);
}

(Note: In case of using Mozilla Firefox 5.0 or Safari 5.0.3, the tagging effect does not work until after refreshing the whole page.)

Very good, now we need the area to be selected again on hovering the links, which are actually ItemTemplates inside a datalist. 

ASP.NET
<asp:DataList ID="dlTaggedFriends" runat="server" RepeatDirection="Horizontal" 
DataSourceID="sdsTags"
ViewStateMode="Disabled">
<ItemTemplate>
<asp:LinkButton ID="lbName" runat="server" onmouseout="SelectEnd()" 
onmouseover='<%#Eval("Coords","preview(\"{0}\");")%>'
Text='<%# Eval("sName") %>'></asp:LinkButton>
(<asp:LinkButton ID="lbRemoveTag" runat="server" 
CommandArgument='<%# Eval("nFriendId") %>'
OnCommand="lbRemoveTag_Command1">remove</asp:LinkButton>)
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</ItemTemplate>
</asp:DataList>

The DatasourceId of datalist dlTaggedFriends , is SqlDataSource sdsTags , which is bound to the view vTag  

vTagsData.jpg 

That's why we concatenated the positions, to pass them as one parameter to the javascript function  preview() on  onmouseover event, where they'll be spitted again . 

JavaScript
function preview(Coords) {
            var arrResult = Coords.split(",");
            var nx1 = arrResult[0];
            var ny1 = arrResult[1];
            var nx2 = arrResult[2];
            var ny2 = arrResult[3];
            var ias = $('#MainContent_Image1').imgAreaSelect({ instance: true });
            ias.setSelection(nx1, ny1, nx2, ny2, true);
            ias.setOptions({ show: true });
            ias.update();
} 

Output

Example.jpg

Drawbacks

  • The tagging effect does not work until after refreshing the whole page when using Mozilla Firefox 5.0 or Safari 5.0.3.

Future Work

  • Free hand selection (instead of rectangle)

Conclusion

  • Tested on Internet Explorer 8, Google Chrome 10.0.6, Mozilla Firefox 5.0 and Safari 5.0.3
  • Feel free to post any questions, modifications, comments

History

  • 20th March, 2011: Initial post 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Egypt Egypt
Enthusiastic programmer/researcher, passionate to learn new technologies, interested in problem solving, data structures, algorithms, AI, machine learning and nlp.

Amateur guitarist/ keyboardist, squash player.

Comments and Discussions

 
QuestionNeed to implement Image Like functionality in Asp.net Pin
Er. Vikas Sangal6-Jul-15 22:16
Er. Vikas Sangal6-Jul-15 22:16 
QuestionGood!! Pin
Primillo21-Feb-13 20:51
Primillo21-Feb-13 20:51 
Questionshowing error Pin
nephy k7-Sep-12 6:16
nephy k7-Sep-12 6:16 
QuestionHow to do Friends.TagFriend(nFriendId, true); method? Pin
sudhakar mr 23-Apr-12 22:14
sudhakar mr 23-Apr-12 22:14 
GeneralMy vote of 3 Pin
NileshKRathod5-Mar-12 18:27
NileshKRathod5-Mar-12 18:27 
GeneralRe: My vote of 3 Pin
Omar Gameel Salem9-Mar-12 1:46
professionalOmar Gameel Salem9-Mar-12 1:46 
GeneralRe: My vote of 3 Pin
nephy k7-Sep-12 6:09
nephy k7-Sep-12 6:09 
QuestionNice one Pin
Ahmed_Said23-Sep-11 12:32
Ahmed_Said23-Sep-11 12:32 
GeneralMy vote of 4 Pin
Sandesh M Patil8-Jul-11 7:06
Sandesh M Patil8-Jul-11 7:06 
GeneralMy vote of 4 Pin
koolprasad200321-Jun-11 3:37
professionalkoolprasad200321-Jun-11 3:37 
GeneralNot working with Chrome and Pin
bayonian16-May-11 4:37
bayonian16-May-11 4:37 
GeneralRe: Not working with Chrome and Pin
easyese26-May-12 15:36
easyese26-May-12 15:36 
QuestionOld database notation? Pin
BerggreenDK20-Mar-11 7:41
BerggreenDK20-Mar-11 7:41 
AnswerRe: Old database notation? Pin
Omar Gameel Salem20-Mar-11 8:15
professionalOmar Gameel Salem20-Mar-11 8:15 
GeneralRe: Old database notation? Pin
BerggreenDK21-Mar-11 2:28
BerggreenDK21-Mar-11 2:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.