Fabric.js 中的像素化图像,使用 sliceHack Resize 滤镜
Pixelated image in Fabric.js with sliceHack Resize filter
有时我无法找到使用调整大小过滤器 (slideHack) 而不获取像素化图像的方法。
我使用 fabric.js 1.7.2
我刚刚在canvas
中添加了图片
fabric.Image.fromURL(url, function(oImg)
{
var scaling = 0.2;
var rFilter = new fabric.Image.filters.Resize({
resizeType: 'sliceHack'
});
oImg.resizeFilters.push(rFilter);
oImg.applyFilters();
oImg.set({
left: 300,
top: 300,
scaleX: scaling,
scaleY: scaling
});
canvas.add(oImg);
canvas.renderAll();
});
当我点击图片或手动调整图片大小时,边缘变得平滑。
当我应用色调滤镜时,它又被像素化了
我找不到触发平滑边缘的函数...
感谢您的帮助。
文档 Introduction to Fabric.js, Part 2 建议使用以下语法,这似乎可以解决问题:
fabric.Image.fromURL('pug.jpg', function(img) {
// add filter
img.filters.push(filter);
// apply filters and re-render canvas when done
img.applyFilters(canvas.renderAll.bind(canvas));
// add image onto canvas
canvas.add(img);
});
将结果与下面代码段中的原始方法进行比较。为了让它工作,我还添加了 { crossOrigin: 'Anonymous' }
(请参阅 AndreaBogazzi 对 的评论)。
var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext("2d");
var url = 'http://i.imgur.com/a47Yxsb.png';
var imgWidth = 770;
function performScaling() {
// Get scaling factor
var scaling = parseFloat(document.getElementById("txtScaling").value);
canvas.clear();
// With original method
fabric.Image.fromURL(url, function(oImg)
{
var rFilter = new fabric.Image.filters.Resize({
resizeType: 'sliceHack'
});
oImg.resizeFilters.push(rFilter);
oImg.applyFilters();
oImg.set({
left: 0,
top: 16,
scaleX: scaling,
scaleY: scaling
});
canvas.add(oImg);
canvas.renderAll();
});
// As suggested in Fabric.js introduction
fabric.Image.fromURL(url, function (oImg) {
oImg.filters.push(new fabric.Image.filters.Resize({
resizeType: 'sliceHack', scaleX: scaling , scaleY: scaling
}));
oImg.set({
left: imgWidth * 1.1 * scaling,
top: 16
});
oImg.applyFilters(canvas.renderAll.bind(canvas));
canvas.add(oImg);
},{ crossOrigin: 'Anonymous' });
// Add labels
canvas.add(new fabric.Text('Pixelated', {
fontFamily: 'Arial',
fontSize: 12,
left: 0.48 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
canvas.add(new fabric.Text('Not pixelated', {
fontFamily: "Arial",
fontSize: 12,
left: 1.58 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
}
#divScaling
{
display: inline-block;
vertical-align: middle;
margin: 6px 32px 16px 0px;
vertical-align: top;
}
#txtScaling
{
width: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.2/fabric.min.js"></script>
<div id="divScaling">
<label for="txtScaling">Scaling factor: </label>
<input id="txtScaling" type="text" value="0.2" />
<button onclick="performScaling()">
Scale
</button>
</div>
<img src="http://i.imgur.com/a47Yxsb.png" style="width: 30px;height: 30px;"/>
<canvas id="c" width="600" height="400"></canvas>
我认为像素化问题已在版本 2 中得到修复。边缘比版本 1.72 更平滑
注意 v2 中的重大更改:
Another breaking change is that the .resizeFilters is no more an array of resize filter. Is a single resizeFilter that you can use when the object is scaled on the canvas.
image.resizeFilter = new fabric.Image.filters.ResizeFilter({type: 'hermite'});
var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext("2d");
var url = 'http://i.imgur.com/a47Yxsb.png';
var imgWidth = 1024;
function performScaling() {
// Get scaling factor
var scaling = parseFloat(document.getElementById("txtScaling").value);
canvas.clear();
// As suggested in Fabric.js introduction
fabric.Image.fromURL(url, function (oImg) {
oImg.set({
left: imgWidth * 1.1 * scaling,
top: 16
});
oImg.scale(scaling);
oImg.resizeFilter = new fabric.Image.filters.Resize({
resizeType: 'sliceHack'
});
oImg.applyResizeFilters();
canvas.add(oImg);
canvas.renderAll();
// canvas.setBackgroundImage(
// oImg,
// () => {
// canvas.renderAll();
// },
// );
},{ crossOrigin: 'Anonymous' });
// Add labels
canvas.add(new fabric.Text('Not pixelated', {
fontFamily: "Arial",
fontSize: 12,
left: 1.58 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
}
#divScaling
{
display: inline-block;
vertical-align: middle;
margin: 6px 32px 16px 0px;
vertical-align: top;
}
#txtScaling
{
width: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.4/fabric.min.js"></script>
<div id="divScaling">
<label for="txtScaling">Scaling factor: </label>
<input id="txtScaling" type="text" value="0.2" />
<button onclick="performScaling()">
Scale
</button>
</div>
<img src="http://i.imgur.com/a47Yxsb.png" style="width: 30px;height: 30px;"/>
<canvas id="c" width="600" height="400"></canvas>
有时我无法找到使用调整大小过滤器 (slideHack) 而不获取像素化图像的方法。 我使用 fabric.js 1.7.2
我刚刚在canvas
中添加了图片fabric.Image.fromURL(url, function(oImg) { var scaling = 0.2; var rFilter = new fabric.Image.filters.Resize({ resizeType: 'sliceHack' }); oImg.resizeFilters.push(rFilter); oImg.applyFilters(); oImg.set({ left: 300, top: 300, scaleX: scaling, scaleY: scaling }); canvas.add(oImg); canvas.renderAll(); });
当我点击图片或手动调整图片大小时,边缘变得平滑。
当我应用色调滤镜时,它又被像素化了
我找不到触发平滑边缘的函数...
感谢您的帮助。
文档 Introduction to Fabric.js, Part 2 建议使用以下语法,这似乎可以解决问题:
fabric.Image.fromURL('pug.jpg', function(img) {
// add filter
img.filters.push(filter);
// apply filters and re-render canvas when done
img.applyFilters(canvas.renderAll.bind(canvas));
// add image onto canvas
canvas.add(img);
});
将结果与下面代码段中的原始方法进行比较。为了让它工作,我还添加了 { crossOrigin: 'Anonymous' }
(请参阅 AndreaBogazzi 对
var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext("2d");
var url = 'http://i.imgur.com/a47Yxsb.png';
var imgWidth = 770;
function performScaling() {
// Get scaling factor
var scaling = parseFloat(document.getElementById("txtScaling").value);
canvas.clear();
// With original method
fabric.Image.fromURL(url, function(oImg)
{
var rFilter = new fabric.Image.filters.Resize({
resizeType: 'sliceHack'
});
oImg.resizeFilters.push(rFilter);
oImg.applyFilters();
oImg.set({
left: 0,
top: 16,
scaleX: scaling,
scaleY: scaling
});
canvas.add(oImg);
canvas.renderAll();
});
// As suggested in Fabric.js introduction
fabric.Image.fromURL(url, function (oImg) {
oImg.filters.push(new fabric.Image.filters.Resize({
resizeType: 'sliceHack', scaleX: scaling , scaleY: scaling
}));
oImg.set({
left: imgWidth * 1.1 * scaling,
top: 16
});
oImg.applyFilters(canvas.renderAll.bind(canvas));
canvas.add(oImg);
},{ crossOrigin: 'Anonymous' });
// Add labels
canvas.add(new fabric.Text('Pixelated', {
fontFamily: 'Arial',
fontSize: 12,
left: 0.48 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
canvas.add(new fabric.Text('Not pixelated', {
fontFamily: "Arial",
fontSize: 12,
left: 1.58 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
}
#divScaling
{
display: inline-block;
vertical-align: middle;
margin: 6px 32px 16px 0px;
vertical-align: top;
}
#txtScaling
{
width: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.2/fabric.min.js"></script>
<div id="divScaling">
<label for="txtScaling">Scaling factor: </label>
<input id="txtScaling" type="text" value="0.2" />
<button onclick="performScaling()">
Scale
</button>
</div>
<img src="http://i.imgur.com/a47Yxsb.png" style="width: 30px;height: 30px;"/>
<canvas id="c" width="600" height="400"></canvas>
我认为像素化问题已在版本 2 中得到修复。边缘比版本 1.72 更平滑
注意 v2 中的重大更改:
Another breaking change is that the .resizeFilters is no more an array of resize filter. Is a single resizeFilter that you can use when the object is scaled on the canvas.
image.resizeFilter = new fabric.Image.filters.ResizeFilter({type: 'hermite'});
var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext("2d");
var url = 'http://i.imgur.com/a47Yxsb.png';
var imgWidth = 1024;
function performScaling() {
// Get scaling factor
var scaling = parseFloat(document.getElementById("txtScaling").value);
canvas.clear();
// As suggested in Fabric.js introduction
fabric.Image.fromURL(url, function (oImg) {
oImg.set({
left: imgWidth * 1.1 * scaling,
top: 16
});
oImg.scale(scaling);
oImg.resizeFilter = new fabric.Image.filters.Resize({
resizeType: 'sliceHack'
});
oImg.applyResizeFilters();
canvas.add(oImg);
canvas.renderAll();
// canvas.setBackgroundImage(
// oImg,
// () => {
// canvas.renderAll();
// },
// );
},{ crossOrigin: 'Anonymous' });
// Add labels
canvas.add(new fabric.Text('Not pixelated', {
fontFamily: "Arial",
fontSize: 12,
left: 1.58 * imgWidth * scaling,
top: 0,
fill: 'black',
originX: 'center'
}));
}
#divScaling
{
display: inline-block;
vertical-align: middle;
margin: 6px 32px 16px 0px;
vertical-align: top;
}
#txtScaling
{
width: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.4/fabric.min.js"></script>
<div id="divScaling">
<label for="txtScaling">Scaling factor: </label>
<input id="txtScaling" type="text" value="0.2" />
<button onclick="performScaling()">
Scale
</button>
</div>
<img src="http://i.imgur.com/a47Yxsb.png" style="width: 30px;height: 30px;"/>
<canvas id="c" width="600" height="400"></canvas>