Load images within datapacket delayed and cache them locally
This commit is contained in:
1 parent
08f4428e28
commit
2f2349ffbb
6 files changed
+132
-20
No files matched your search
@@ -68,6 +68,13 @@ namespace ServerLib
|
|||||||
set { CServer.getSiteFile = value; }
|
set { CServer.getSiteFile = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static GetDelayedImageDelegate getDelayedImage;
|
||||||
|
public static GetDelayedImageDelegate GetDelayedImage
|
||||||
|
{
|
||||||
|
internal get { return CServer.getDelayedImage; }
|
||||||
|
set { CServer.getDelayedImage = value; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region songs
|
#region songs
|
||||||
|
|||||||
@@ -96,6 +96,12 @@ namespace ServerLib
|
|||||||
UriTemplate = "/img/{filename}")]
|
UriTemplate = "/img/{filename}")]
|
||||||
Stream GetImgFile(String filename);
|
Stream GetImgFile(String filename);
|
||||||
|
|
||||||
|
[OperationContract]
|
||||||
|
[WebInvoke(Method = "GET",
|
||||||
|
ResponseFormat = WebMessageFormat.Json,
|
||||||
|
UriTemplate = "/delayedImage?id={id}")]
|
||||||
|
Base64Image GetDelayedImage(String id);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region songs
|
#region songs
|
||||||
@@ -382,6 +388,11 @@ namespace ServerLib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Base64Image GetDelayedImage(string id)
|
||||||
|
{
|
||||||
|
return CServer.GetDelayedImage(id);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region songs
|
#region songs
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace ServerLib
|
|||||||
|
|
||||||
public delegate byte[] GetSiteFileDelegate(string filename);
|
public delegate byte[] GetSiteFileDelegate(string filename);
|
||||||
|
|
||||||
|
public delegate Base64Image GetDelayedImageDelegate(string hashedFilename);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -66,6 +68,9 @@ namespace ServerLib
|
|||||||
[DataMember]
|
[DataMember]
|
||||||
private string base64Data = "";
|
private string base64Data = "";
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
private string imageId = "";
|
||||||
|
|
||||||
public Base64Image(Image img, ImageFormat format)
|
public Base64Image(Image img, ImageFormat format)
|
||||||
{
|
{
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new MemoryStream();
|
||||||
@@ -74,6 +79,11 @@ namespace ServerLib
|
|||||||
base64Data = "data:image/" + formatString + ";base64," + Convert.ToBase64String(ms.ToArray());
|
base64Data = "data:image/" + formatString + ";base64," + Convert.ToBase64String(ms.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Base64Image(string imageId)
|
||||||
|
{
|
||||||
|
this.imageId = imageId;
|
||||||
|
}
|
||||||
|
|
||||||
public Image getImage()
|
public Image getImage()
|
||||||
{
|
{
|
||||||
string onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + (";base64,").Length);
|
string onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + (";base64,").Length);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Vocaluxe.Base.Server
|
|||||||
_Clients = new Dictionary<int, CClientHandler>();
|
_Clients = new Dictionary<int, CClientHandler>();
|
||||||
|
|
||||||
_Server = new CServer(CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
|
_Server = new CServer(CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
|
||||||
//_Server = new CServer(RequestHandler, CConfig.ServerPort, CConfig.ServerPassword);
|
//TODO: remove CConfig.ServerPassword
|
||||||
|
|
||||||
CServer.SendKeyEvent = sendKeyEvent;
|
CServer.SendKeyEvent = sendKeyEvent;
|
||||||
CServer.GetProfileData = getProfileData;
|
CServer.GetProfileData = getProfileData;
|
||||||
@@ -62,6 +62,7 @@ namespace Vocaluxe.Base.Server
|
|||||||
CServer.GetUserRole = getUserRole;
|
CServer.GetUserRole = getUserRole;
|
||||||
CServer.SetUserRole = setUserRole;
|
CServer.SetUserRole = setUserRole;
|
||||||
CServer.GetUserIdFromUsername = getUserIdFromUsername;
|
CServer.GetUserIdFromUsername = getUserIdFromUsername;
|
||||||
|
CServer.GetDelayedImage = getDelayedImage;
|
||||||
|
|
||||||
_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
|
_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
|
||||||
Controller.Init();
|
Controller.Init();
|
||||||
@@ -262,9 +263,7 @@ namespace Vocaluxe.Base.Server
|
|||||||
{
|
{
|
||||||
if (File.Exists(avatar.FileName))
|
if (File.Exists(avatar.FileName))
|
||||||
{
|
{
|
||||||
Image avatarImage = Image.FromFile(avatar.FileName);
|
profileData.Avatar = new Base64Image(createDelayedImage(avatar.FileName));
|
||||||
//TODO: Convert??? and Resize?
|
|
||||||
profileData.Avatar = new Base64Image(avatarImage, avatarImage.RawFormat);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return profileData;
|
return profileData;
|
||||||
@@ -315,6 +314,8 @@ namespace Vocaluxe.Base.Server
|
|||||||
|
|
||||||
#region website
|
#region website
|
||||||
|
|
||||||
|
private static Dictionary<string, string> delayedImagePath = new Dictionary<string, string>();
|
||||||
|
|
||||||
private static byte[] getSiteFile(string filename)
|
private static byte[] getSiteFile(string filename)
|
||||||
{
|
{
|
||||||
string path = "Website/" + filename;
|
string path = "Website/" + filename;
|
||||||
@@ -335,6 +336,45 @@ namespace Vocaluxe.Base.Server
|
|||||||
return File.ReadAllBytes(path);
|
return File.ReadAllBytes(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string createDelayedImage(string filename)
|
||||||
|
{
|
||||||
|
byte[] by = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(filename));
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (byte b in by)
|
||||||
|
{
|
||||||
|
sb.Append(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
string hashedFilename = sb.ToString();
|
||||||
|
|
||||||
|
if (!delayedImagePath.ContainsKey(hashedFilename))
|
||||||
|
{
|
||||||
|
delayedImagePath.Add(hashedFilename, filename);
|
||||||
|
}
|
||||||
|
return hashedFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Base64Image getDelayedImage(string hashedFilename)
|
||||||
|
{
|
||||||
|
if (!delayedImagePath.ContainsKey(hashedFilename))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Image not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
string fileName = delayedImagePath[hashedFilename];
|
||||||
|
|
||||||
|
if (File.Exists(fileName))
|
||||||
|
{
|
||||||
|
Image image = Image.FromFile(fileName);
|
||||||
|
return new Base64Image(image, image.RawFormat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Image not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region songs
|
#region songs
|
||||||
@@ -376,8 +416,7 @@ namespace Vocaluxe.Base.Server
|
|||||||
result.SongId = song.ID;
|
result.SongId = song.ID;
|
||||||
if (includeCover)
|
if (includeCover)
|
||||||
{
|
{
|
||||||
Image cover = Image.FromFile(song.Folder + "\\" + song.CoverFileName);
|
result.Cover = new Base64Image(createDelayedImage(song.Folder + "\\" + song.CoverFileName));
|
||||||
result.Cover = new Base64Image(cover, cover.RawFormat);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -54,3 +54,12 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.imageLoaderImg {
|
||||||
|
height:45px;
|
||||||
|
width:45px;
|
||||||
|
background: url(images/ajax-loader.gif);
|
||||||
|
background-size: 46px 46px;
|
||||||
|
-webkit-border-radius: 36px;
|
||||||
|
border-radius: 36px;
|
||||||
|
}
|
||||||
+50
-14
@@ -132,12 +132,9 @@ function initPageLoadHandler() {
|
|||||||
|
|
||||||
function handleDisplayProfileData(data) {
|
function handleDisplayProfileData(data) {
|
||||||
$('#playerName').prop("value", data.PlayerName);
|
$('#playerName').prop("value", data.PlayerName);
|
||||||
if (data.Avatar && data.Avatar.base64Data) {
|
|
||||||
$('#playerAvatar').prop("src", data.Avatar.base64Data);
|
addImage($('#playerAvatar')[0], data.Avatar, "img/profile.png");
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('#playerAvatar').prop("src", "img/profile.png");
|
|
||||||
}
|
|
||||||
$('#playerAvatar').data("changed", false);
|
$('#playerAvatar').data("changed", false);
|
||||||
$('#playerType').prop("value", data.Type);
|
$('#playerType').prop("value", data.Type);
|
||||||
$('#playerDifficulty').prop("value", data.Difficulty);
|
$('#playerDifficulty').prop("value", data.Difficulty);
|
||||||
@@ -196,9 +193,12 @@ function initPageLoadHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var profile in data) {
|
for (var profile in data) {
|
||||||
$('<li id="ProfileSelectLine_' + data[profile].ProfileId + '"> <a href="#"> <img src="' + ((data[profile].Avatar && data[profile].Avatar.base64Data) ? data[profile].Avatar.base64Data : "img/profile.png") + '"> <h2>' + data[profile].PlayerName + '</h2> <p>Click here to show the profile of ' + data[profile].PlayerName + '</p> </a> </li>')
|
var img = $('<li id="ProfileSelectLine_' + data[profile].ProfileId + '"> <a href="#"> <img> <h2>' + data[profile].PlayerName + '</h2> <p>Click here to show the profile of ' + data[profile].PlayerName + '</p> </a> </li>')
|
||||||
.appendTo('#selectProfileList')
|
.appendTo('#selectProfileList')
|
||||||
.click(handleProfileSelectLineClick);
|
.click(handleProfileSelectLineClick)
|
||||||
|
.find("img")[0];
|
||||||
|
|
||||||
|
addImage(img, data[profile].Avatar, "img/profile.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#selectProfileList').listview('refresh');
|
$('#selectProfileList').listview('refresh');
|
||||||
@@ -221,12 +221,7 @@ function initPageLoadHandler() {
|
|||||||
$('#displaySongTitle').text("No current song");
|
$('#displaySongTitle').text("No current song");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Cover && result.Cover.base64Data) {
|
addImage($('#displaySongCover')[0], result.Cover, "img/noCover.png");
|
||||||
$('#displaySongCover').prop("src", result.Cover.base64Data);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('#displaySongCover').prop("src", "img/noCover.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.Artist != null) {
|
if (result.Artist != null) {
|
||||||
$('#displaySongArtist').text(result.Artist);
|
$('#displaySongArtist').text(result.Artist);
|
||||||
@@ -549,3 +544,44 @@ function initKeyboardPageHandler() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cachedImages = {};
|
||||||
|
|
||||||
|
function delayedImageLoad(elem, id, fail) {
|
||||||
|
if (elem && id) {
|
||||||
|
if (cachedImages[id]) {
|
||||||
|
elem.src = cachedImages[id].base64Data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.src = "";
|
||||||
|
$(elem).addClass("imageLoaderImg");
|
||||||
|
$.ajax({
|
||||||
|
url: "delayedImage?id=" + id,
|
||||||
|
headers: { "session": sessionId }
|
||||||
|
}).done(function (result) {
|
||||||
|
$(elem).removeClass("imageLoaderImg");
|
||||||
|
elem.src = result.base64Data;
|
||||||
|
cachedImages[id] = result;
|
||||||
|
}).fail(function () {
|
||||||
|
$(elem).removeClass("imageLoaderImg");
|
||||||
|
if (fail) {
|
||||||
|
elem.src = fail;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addImage(img, base64Image, defaultImg) {
|
||||||
|
if (base64Image && (base64Image.base64Data || base64Image.imageId)) {
|
||||||
|
if (base64Image.base64Data) {
|
||||||
|
$(img).prop("src", base64Image.base64Data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delayedImageLoad(img, base64Image.imageId, defaultImg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(img).prop("src", defaultImg);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user