ArthurHub / ArthurHub/HTML-Renderer
Callback provided images not respecting CSS imposed size
- Linguagem predominante
- C#
- Estrelas
- 1.4k
- Forks
- 550
- Merge médio
- 14d 9h
- PRs com merge (30d)
- 1
Descrição
This is an odd case. To support SVG I am using the imageLoad event.
Basically it queries the URL supplied, constructs an instance of SvgDocument and gets height and width from attributes or the style property. Then it works out the pixel dimensions according to e.Graphics.DpiX, constructs an instance of Bitmap of this size and renders into it.
This all works, and the size is what I expect -- a QR code styled to be 20mm tall should be 472x472 pixels on a 600dpi printer, and that's exactly the size of the bitmap produced.
However, this is then drawn on the page at a size that would be correct were it a 96dpi image. This causes it to be way too big. By default bitmaps are created with this resolution so I tried setting the resolution of the bitmap to 600, but it didn't help.
Is this a bug or is there some way to make it respect the image DPI when doing layout and rendering?
imageLoad: (sender, args) =>
{
try
{
var src = args.Src;
if (src.IndexOf(':') == -1)
{
var sep = src.StartsWith("/") ? string.Empty : "/";
src = $"{baseUrl}{sep}{src}";
}
var path = Path.GetExtension(args.Src);
if (path != null && path.Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(src);
SvgDocument svgDoc = SvgDocument.Open(xmlDoc);
svgDoc.Ppi = (int)e.Graphics.DpiX;
if (args.Attributes.Any(attr => attr.Key.ToLower() == "style"))
{
var style = args.Attributes.Single(kvp => kvp.Key.ToLower() == "style").Value
.Split(new char[] { ':', ';' })
.Select(x => x.Trim().ToLower()).ToArray();
var i = Array.IndexOf(style, "height");
if (i > -1) { svgDoc.Height = style[i + 1].ToSvgUnit(); }
i = Array.IndexOf(style, "width");
if (i > -1) { svgDoc.Width = style[i + 1].ToSvgUnit(); }
}
int h = (int)svgDoc.Height.ToDeviceValue(null, UnitRenderingType.Other, svgDoc);
int w = (int)svgDoc.Width.ToDeviceValue(null, UnitRenderingType.Other, svgDoc);
Bitmap svgImg = new Bitmap(w, h, PixelFormat.Format32bppArgb);
svgImg.SetResolution(e.Graphics.DpiX, e.Graphics.DpiY);
svgDoc.Draw(svgImg);
args.Callback(svgImg);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
Guia de contribuição
Nenhum guia de contribuição indexado para este repositório
Direção de pesquisa
Comece reproduzindo o issue #155 com o callback imageLoad mostrado, um SVG dimensionado para 20mm e um contexto gráfico de 600dpi. Rastreie o caminho de layout e renderização da imagem para comparar o bitmap de 472×472 com seu tamanho exibido. Considera-se concluído quando o dimensionamento CSS e o DPI do bitmap produzem o tamanho físico pretendido sem ampliar a imagem.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- csharp
- Domínio
- frontend
- Tipo de issue
- Bug
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 35/100