C# 通过外键获取图像
我有一张表,上面有关于产品照片的数据,这个表和产品表有关系,产品可能不仅仅是图片。我的代码做得很好,通过C# 通过外键获取图像,c#,.net,asp.net,C#,.net,Asp.net,我有一张表,上面有关于产品照片的数据,这个表和产品表有关系,产品可能不仅仅是图片。我的代码做得很好,通过productID查询字符串获取产品的所有图像,但只检索到第一个图像。请注意,处理程序页面中的ProductID是Photobankimages表中的外键, 我还注意到,productID具有ID表的值,而不是productID: 存储过程: ALTER proc [dbo].[SP_GetPhotoBank] ( @ProductID Int ) as SELECT ID, Pro
productID
查询字符串获取产品的所有图像,但只检索到第一个图像。请注意,处理程序页面中的ProductID
是Photobank
images表中的外键,
我还注意到,productID
具有ID
表的值,而不是productID
:
存储过程:
ALTER proc [dbo].[SP_GetPhotoBank]
(
@ProductID Int
)
as
SELECT ID, ProductID, DesignImage
FROM ProductImages
where ProductID=@ProductID
标记:
<div>
<asp:DataList ID="DLProduct" runat="server" OnItemDataBound="DLProduct_ItemDataBound">
<ItemTemplate>
<table style="width: 100%;">
<tr>
<td>
<asp:Label ID="LblModel" runat="server" Text='<%#Eval("Model") %>' Style="color: #CC3300"></asp:Label>
</td>
<td>
</td>
</tr>
<tr>
<td colspan="2">
</td>
</tr>
<tr>
<td>
<asp:Image ID="IMGPhotoBank" runat="server" ImageUrl='<%#Eval("ProductID","~/Handlers/PhotoBankByProductID.ashx?ProductID={0}") %>' />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
</div>
我认为您需要遍历数据读取器中的数据,因为当前您将只读取第一个结果,然后关闭数据读取器
while(dr.Read())
{
// add results to some collection
}
// close the reader and tidy up
dr.Close();
dr.Dispose();
// now render your data
您需要将数据库中的所有图像合并到一个位图中,然后将此合并位图发送到浏览器 基本上,这些步骤是: 首先,在数据读取器上循环时,将图像数据的
字节[]
存储在列表中
while(dr.Read())
{
// add results to some collection
}
// close the reader and tidy up
dr.Close();
dr.Dispose();
// now render your data
第二步:迭代上述列表,并使用以下代码为每个字节[]
构建位图:
MemoryStream stream = new MemoryStream(currentData);
Bitmap bitmap = new Bitmap(stream);
计算每个位图的高度和最大宽度之和,并使用该高度和宽度构建新的位图对象以保存合并的图像:
Bitmap mergedImages = new Bitmap(maxWidth, totalHeight);
第三步:使用以下代码将上面构建的图像(从每个字节[]
构建的位图
)添加到mergedImages
:
int yPos = 0;
using (Graphics g = Graphics.FromImage(mergedImages))
{
foreach (Bitmap curBitmap in arrBitmaps)
{
g.DrawImage(curBitmap, 0, yPos);
yPos += curBitmap.Height;
}
}
最后一步是将合并的位图发送到浏览器:
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Jpeg);
Response.BinaryWrite(stream.GetBuffer());
}
我知道这可能看起来很复杂,但我相信一步一步地做最终你会明白的。你不能在一个请求中向浏览器发送多个图像。基本上你有两个选择:
迭代页面中的图像
将所有图像合并到一个文件中,如建议的那样
在大多数情况下,选项1可以。您需要做的是:
- 确保每个图像都可以通过唯一的密钥访问。
处理程序应为每个请求返回1个图像。因此,您的URL看起来类似于:
~/Handlers/PhotoBank.ashx?ImageID={0}
- 列出每个产品的图像,以便您可以在数据绑定期间访问它们。我真的不知道在你的申请中会是什么样子。您可以将图像标记包装在中继器中,以在图像列表中迭代
您的代码有很多缺失。但我会尽可能地把它画出来
1) 数据列表必须生成对象列表。通过打开页面并查看产品列表来验证这一点。他们可能有一堆破碎的图像
2) 查看输出页面的源html。您将看到一些损坏产品图像的URL。URL看起来正确吗?它可能类似于/myproductimage.ashx?pid=5554172
3) 正确生成URL后,忽略产品页面。从现在开始,您将测试图像处理程序。最好这样考虑,因为它实际上与您的数据网格无关
4) 将产品图像处理程序URL放入浏览器的栏中,看看会出现什么。可能没什么。但如果它是HTTP404,那么您知道您的处理程序没有正确连接。我喜欢使用.ashx处理程序来完成这类任务。它更合适,而且是一个完整的aspx页面
5) 最后,在正确调用处理程序之后。根据数据库中存储的内容,将Response.ContentType设置为“image/jpeg”或“image/png”。我建议在图像数据旁边添加一列,这样您就可以知道数据的格式
如果这还不够清楚,请联系我,我可以在这里为您发布一个旧的产品图像处理程序代码作为示例。出现问题的原因是您试图在向处理程序发出的同一请求中处理多个图像,而不是确保公开每个图像都返回一个图像的URL(对处理程序的每个请求应仅返回一个图像)
换句话说,您现在有了一个处理程序,它公开了如下入口点:
~/Handlers/PhotoBankByProductID.ashx?ProductID={0}
~/Handlers/PhotoBankByProductID.ashx?ProductID={0}&ID={1}
但是,您应该考虑重新构建处理程序,以便它像这样公开入口点URL:
~/Handlers/PhotoBankByProductID.ashx?ProductID={0}
~/Handlers/PhotoBankByProductID.ashx?ProductID={0}&ID={1}
其中,{1}
是ProductImages
表中记录的ID
确保此URL同时返回由ProductID
和
检索的图像
然后,在数据列表
中,确保使用这种新的URL。为此,在每个项目模板
中检索每个显示产品的图像的ID
-s,然后使用另一个嵌套的类似列表的控件,为当前产品ID
的每个产品图像显示图像元素>
虽然为每个ItemTemplate
检索图像ID
-s似乎有点开销。在这种情况下,如果您有足够的雄心壮志,可以先检索所有需要的产品,然后检索与每个产品相关联的所有图像(在一个结果集中全部),然后绑定到产品列表,然后,对于每个嵌套的产品图像列表,从相同的结果集中查找相应的图像
为了使内部列表绑定,您将需要OnItemDataBound
事件处理程序,我认为这是一个很好的起点
我希望这有帮助!问题是?!?不清楚你在这里问什么……SP_GetPhotoBank内部的查询是什么样的?将proc[dbo].[SP_GetPhotoBank](@ProductID Int)改为ProductImages中的SELECT ID、ProductID、DesignImage,其中ProductID=@ProductIDI执行了此操作,但在渲染时只有一个图像(dr.Read()&&dr!=null){Byte[]bytes2=(Byte[])dr[“DesignImage”];context.Response.BinaryWrite(bytes2);}dr.Close();dr.Dispose();@KareemSaad:只是一个提示:dr.Read()&&dr!=null
没有意义。在执行Read()之前,您可能需要检查dr
是否为null