Am I being thick? Also, if I want to deliver different 404 images depending on the path requested, is it just a case of doing an "if/then" in the GetImage or was the prefix attribute intended to be used for this? Apologies for not 'getting' it!
Which version of ImageProcessor.Web are you using? If it's the package from here it's not up to date so probably won't have the functionality built in to do what you want. Nuget is always the best location.
In answer to your second question you would use if/else as the prefix setting is for identifying which service to use. That prefix is the start of the url you would use to get your image.
Sorry, I should have specified - yes I'm working from nuget. I'm not actually using this in the umbraco context, I just figured this forum would be a good place to ask.
So, are you saying I've gotten the configuration right? I assume that if I only have one service (my custom one), the system will automatically use that for requests with image extensions then and that I don't need to use the prefix.
Copy the source for LocalFileImageService and give it your own name e.g. CustomLocalFileImageService and the correct namespace.
Modify the GetImage method as below.
Modify /config/security.config and use <service name="CustomLocalFileImageService" type="YourNamespace.CustomLocalFileImageService, YourNamespace" />
GetImage method:
if (!fileInfo.Exists)
{
var pathLower = path.ToLower();
if (path.ToLower().Contains("somepattern"))
path = System.Web.Hosting.HostingEnvironment.MapPath("~/images/your-custom-image.jpg");
else
throw new HttpException(404, "No image exists at " + path);
}
However I couldn't make it work although path is replaced with new value.
public class CustomLocalFileImageService : LocalFileImageService
{
/// <summary>
/// Gets the image using the given identifier.
/// </summary>
/// <param name="id">
/// The value identifying the image to fetch.
/// </param>
/// <returns>
/// The <see cref="System.Byte"/> array containing the image data.
/// </returns>
public override async Task<byte[]> GetImage(object id)
{
string path = id.ToString();
byte[] buffer;
// Check to see if the file exists.
if (!File.Exists(path))
{
if (path.ToLower().Contains("\\img\\products\\"))
path = System.Web.Hosting.HostingEnvironment.MapPath("~/dist/img/no-product-image.jpg");
else
throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path);
throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path);
}
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
{
buffer = new byte[file.Length];
await file.ReadAsync(buffer, 0, (int)file.Length);
}
return buffer;
}
}
The class is wrapped inside a namespace My.Library.ImageProcessor and in config/imageprocessor/security.config I have the following:
The issue seems to be because of the last line here:
throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path);
I have changed this part to:
// Check to see if the file exists.
if (!File.Exists(path))
{
if (path.ToLower().Contains("\\img\\products\\"))
{
path = System.Web.Hosting.HostingEnvironment.MapPath("~/dist/img/no-product-image.jpg");
if(!File.Exists(path))
throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path);
}
else
{
throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path);
}
}
Implementing your own services
Hi there,
Great tool. But can't figure out how to implement my own
IImageService
.I simply want to have a custom images instead of a 404. So I create a new class
CustomLocalFileImageService
that implementsIImageService
.I copy the source for
LocalFileImageService
and modify theGetImage
method to return a different image if the file doesn't exist.How do I actually set up ImageProcessor to use this? I have installed ImageProcessor.Config. I tried changing my security config to:
Am I being thick? Also, if I want to deliver different 404 images depending on the path requested, is it just a case of doing an "if/then" in the
GetImage
or was theprefix
attribute intended to be used for this? Apologies for not 'getting' it!Hola,
Which version of ImageProcessor.Web are you using? If it's the package from here it's not up to date so probably won't have the functionality built in to do what you want. Nuget is always the best location.
In answer to your second question you would use
if/else
as the prefix setting is for identifying which service to use. That prefix is the start of the url you would use to get your image.Hi James,
Sorry, I should have specified - yes I'm working from nuget. I'm not actually using this in the umbraco context, I just figured this forum would be a good place to ask.
So, are you saying I've gotten the configuration right? I assume that if I only have one service (my custom one), the system will automatically use that for requests with image extensions then and that I don't need to use the prefix.
Yeah, that should be how it works. I'll have to double check though to be sure I haven't made a mistake somewhere.
If this is not Umbraco based I suggest we move this somewhere else. I have a gitter chatroom set up. https://gitter.im/JimBobSquarePants/ImageProcessor
Seems to be working now. I was running the project using the development server rather than IIS - pretty sure that's what it was.
For future reference, to implement custom 404 images:
Install ImageProcessor, ImageProcessor.Web, ImageProcessor.Config
Copy the source for LocalFileImageService and give it your own name e.g.
CustomLocalFileImageService
and the correct namespace.Modify the GetImage method as below.
Modify
/config/security.config
and use<service name="CustomLocalFileImageService" type="YourNamespace.CustomLocalFileImageService, YourNamespace" />
GetImage method:
I'm glad you got it working! :)
I wonder what was going wrong?
In newer versions of ImageProcessor
GetImage
is allowed to override. https://github.com/JimBobSquarePants/ImageProcessor/commit/b453b38c501d3a69cdfe6c30c36903e2d1e45472#diff-c4f527cd14023f61321629ab67a30185However I couldn't make it work although path is replaced with new value.
The class is wrapped inside a namespace
My.Library.ImageProcessor
and inconfig/imageprocessor/security.config
I have the following:Am I missing something?
/Bjarne
Okay, now it is working :)
No sure if ImageProcessor just had the old request cached even I had recycled the application and cleared brower cache.
But now I get the
no-product-image.jpg
it the psychical file e.g./img/products/123456.jpg
doesn't exists.The issue seems to be because of the last line here:
I have changed this part to:
is working on a reply...