首页 > 解决方案 > ImageMagic 无法捕获异常

问题描述

我使用多线程代码在 linux 中通过 Imagemagick 生成了数百万个 bmp,但由于某种原因,我得到了其中一个我无法处理的错误(没有堆栈跟踪):

dotnet: MagickCore/pixel.c:138: ClonePixelChannelMap: Assertion 'channel_map != (PixelChannelMap *) NULL' failed.

或者

dotnet: MagickCore/semaphore.c:452: UnlockSemaphoreInfo: Assertion 'semaphore_info != (SemaphoreInfo *) NULL' failed.

或者

dotnet: MagickCore/option.c:2137: CloneImageOptions: Assertion 'clone_info->signature == MagickCoreSignature' failed.

我的try - catch块不处理这些错误,所以我的程序立即关闭。

错误是非常随机的,因为 Imagemagick 在另一次尝试中的相同输入通过而没有错误。

我使用Include="Magick.NET-Q16-x64" Version="7.11.0.0"

我还尝试了“Magick.NET-Q8-x64”和以前版本的 imagemagic,结果相同。

Linux 4.18.0-3-amd64 #1 SMP Debian 4.18.20-2 (2018-11-23) x86_64 GNU/Linux

这是来自线程的代码(我用 9 个线程运行应用程序)

    public virtual void GeneratePictureForCurrSpin()
    {
        do
        {
            GenerateInternal();
        } while (!isAllPicturesGenerated());
    }

    public override void GenerateInternal()
    {
        symbols = symbolParser.ParseSymbols(config, spins[currLocalSpin].symbols);
        img = (MagickImage)SpinGenerator.rl.emptyImg.Clone();
        bgImg = SpinGenerator.rl.bg;
        img.Composite(bgImg, new PointD(config.BgX, config.BgY),ImageMagick.CompositeOperator.Over);
        reelsBgImg = SpinGenerator.rl.reelsBg;
        img.Composite(reelsBgImg, CompositeOperator.Over);
        PointD startPoint = new PointD(config.StartOffsetX, config.StartOffsetY);
        MagickImage sym;
        for(int i = 0; i < symbols.Count; i++)
        {
            List<int> symbolsOnReel = symbols[i];
            for(int j = 0; j < symbolsOnReel.Count; j++)
            {
                var newPoint = new PointD(startPoint.X + i * (config.SymbolWidth + config.OffsetX), startPoint.Y + j * (config.SymbolHeight + config.OffsetY));
                sym = SpinGenerator.rl.symbols[symbolsOnReel[j]-1];
                img.Composite(sym, newPoint, ImageMagick.CompositeOperator.Over);
            }
        }

        bool isFreeSpin = (spins[currLocalSpin].betValue == 0)?true:false; 
        GenerateBottomBar(isFreeSpin);
        ShowTokensValue(spins[currLocalSpin].coins);
        ResizeImage();
        int fileNr = spins[currLocalSpin].spinNr;
        String dir = "Resources/Result/" + GAME_NAME + "/" + betValue;
        SaveImg(dir , fileNr);
        img.Dispose();
        IncrementSpinValues();
    }


    public virtual void GenerateBottomBar(bool isFreeSpin)
    {
        var pos = (isFreeSpin)?1:0;
        bottomBar = SpinGenerator.rl.bottomBars[pos];
        PointD startPoint = new PointD(0,config.BgHeight);
        img.Composite(bottomBar,startPoint);
    }

    private void ShowTokensValue(int tokens)
    {
        if(tokens < 10)
        {
            var tokenValueImg = SpinGenerator.rl.tokensValues[tokens];
            tokenValueImg.Resize(90,60);
            img.Composite(tokenValueImg, new PointD(tokenValueStartX + tokenValueImgWidth, tokenValueStartY),ImageMagick.CompositeOperator.Over);
        }
        else{
            int a = tokens / 10;
            int b = tokens % 10;
            var tokenValueImgA = SpinGenerator.rl.tokensValues[a];
            tokenValueImgA.Resize(90,55);
            img.Composite(tokenValueImgA, new PointD(tokenValueStartX, tokenValueStartY),ImageMagick.CompositeOperator.Over);
            var tokenValueImgB = SpinGenerator.rl.tokensValues[b];
            tokenValueImgB.Resize(90,55);
            img.Composite(tokenValueImgB, new PointD(tokenValueStartX+ tokenValueImgWidth, tokenValueStartY),ImageMagick.CompositeOperator.Over);
        }
        var tokensTxtImg = SpinGenerator.rl.tokensTxt;
        img.Composite(tokensTxtImg, new PointD(tokenTxtStartX, tokenTxtStartY),ImageMagick.CompositeOperator.Over);
    }

    internal void ResizeImage()
    {
        img.Format = ImageMagick.MagickFormat.Bmp3;
        img.Depth = 16;
        img.Resize(new MagickGeometry("600, 450!"));
        //img.Quality = 100;
    }

    internal void SaveImg(String dir , int fileNr)
    {
        System.IO.Directory.CreateDirectory(dir);
        img.Write(dir + "/" +"s" + fileNr + ".bmp");
        ClearImg();
    }

    internal virtual void IncrementSpinValues()
    {
        currLocalSpin++;
        currSpin++;
    }

标签: c#imagemagick

解决方案


推荐阅读